오늘은 Room database에 대해 공부해보고 적용해 보는 시간을 가져보려고 합니다.
일단 Room Database 이란?
이전에 제가 학교에 다닐때 약간 메세지를 전송 하고 받는 메세지 앱 같은걸 구현한적이 있습니다.
그때는 서버가 없어서
A ->B 메세지 전송시 핸드폰에 메세지를 저장했습니다.
그때 썼던게 MySQL 이었던 기억이 있습니다. 
그럼 왜 MySql 이라는 대중적인놈이 있는데 왜 RoomDatabase을 사용할까 를 알아 봤습니다
쿼리 검증
mySQL 을 사용할때를 곰곰히 생각해보면
일단 한번 APP을 돌려놓고 예외 상황이 생겼는지  체크 했던 무식한 방법을 저는 썼던거 같습니다
(제가 무식한거지 다른사람은 아닙니다)
그러나 Roomdatabase 는 코드를 개발할떄 쿼리문의 오타나 오류를 찾아줍니다. 
LiveData 와 Rxjava 사용가능
스키마가 바뀌었을 때 영향 받는 SQL 쿼리를 직접 바꾸지 않아도 된다.
상용구 코드 없이 DB 객체를 자바 객체에 매핑한다.
이렇게 가 있는거 같습니다. LiveData 와 Rxjava 사용가능 에서 구글에서 적극 권장한다는 느낌을 받았습니다.
일단 Roomdatabase을 사용하려면 라이브러리를 다운 받아야 한다.
https://developer.android.com/training/data-storage/room?hl=ko
여기를 가서 다운을 받아보자.

와중에 개발자 가이드 문서를 보다보니 이런 안내 메세지가 있다. 싱글톤으로 구현하라 알겠습니다 한번 해봐야지요
일단 MainApplication 을 만들어 봅시다.
class MainApplication : Application() {
    companion object{
        lateinit var appContext : Context
    }
    override fun onCreate() {
        super.onCreate()
        appContext = applicationContext
    }
}
이러한 클래스를 만들어주고
Mainfest 파일에
  <application
        android:name=".MainApplication"
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
의 name에 MainApplication을 지정해 줬습니다.
@Database(
    entities = [
        FavoriteBookList :: class ,
        SearchList :: class
    ],
    version = 1
)
abstract class AppdataBase : RoomDatabase() {
    abstract fun dataDao () : DataDao
    companion object{
        const val TABLE_SEARCH_LIST = "searchList"
        const val TABLE_FAVORITE_BOOK = "favoriteBook"
        @Volatile
        private var instance : AppdataBase ? = null
 
        fun getInstance() : AppdataBase{
            instance ?: synchronized(this){
                instance = Room.databaseBuilder(MainApplication.appContext ,
                    AppdataBase :: class.java,
                    "database")
                    .allowMainThreadQueries()
                    .fallbackToDestructiveMigration()
                    .build()
            }
            return instance!!
        }
    }
}
그후 검색어를 저장을 위한 table 와 즐겨찾기 책 table 을 만들었습니다. 싱글톤으로 만들었습니다.
참고로 @Volatile  이란? 
자 그럼 저장할 객체를 만들어 봅시다
@Entity(
    tableName = AppdataBase.TABLE_SEARCH_LIST
)
data class SearchList(
    @PrimaryKey var time : String ,
    @ColumnInfo var search : String
)
-------------------------------------------------------
@Entity(
    tableName = AppdataBase.TABLE_FAVORITE_BOOK
)
data class FavoriteBookList(
    @PrimaryKey var time  : String,
    @ColumnInfo var title : String,
    @ColumnInfo var writer : String ,
    @ColumnInfo var link : String
)
제가 만든 객체들입니다. 제가 Datatbase을 만들때 table의 식별키를 만들어야 한다 라고 배웠던 기억이 있습니다.
그래서 보면
검색 기록 같은 경우는 사용자가 검색을 했던시간(@PrimaryKey var time : String)
책같은 경우는 발행 시간 (@PrimaryKey var time  : String) 으로 했습니다. 
왜 이걸로 했냐 시간 같은 경우는
검색 기록 같은 경우는 밀리세컨드 까지 기록을 해서 겹칠일이 없고
발행일자도 분초 까지 나와 겹칠일이 없다고 생각했습니다
PrimaryKey는 겹치는게 없어야 합니다
자 그럼 객체도 만들었으니 insert delete 도 만들어 봐야지요?
@Dao
interface DataDao {
    @Insert
    fun insertSearchList(data : SearchList)
    @Insert
    fun insertFavoriteBook(data : FavoriteBookList)
    @Query("SELECT * FROM ${AppdataBase.TABLE_SEARCH_LIST}")
    fun getSearchList() : List<SearchList>
    @Query("SELECT * FROM ${AppdataBase.TABLE_FAVORITE_BOOK}")
    fun getFavoriteBookList() : List<FavoriteBookList>
}
간단 하지요? insert 같은 경우는 @Insert 만 넣어주면 되고
원하는 데이터가 있으면 @Query을 작성해서 저런식으로 Table 이름만 넘겨 주면 됩니다. 
여기서 주의할 점은 @Dao 을 꼭 써 줘야 합니다. 안그럼 빌드도 못합니다
자 그럼 결과는?

잘 저장된거 같습니다.
그럼 여기까지 읽어주셔서 감사합니다