오늘은 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 을 꼭 써 줘야 합니다. 안그럼 빌드도 못합니다
자 그럼 결과는?
잘 저장된거 같습니다.
그럼 여기까지 읽어주셔서 감사합니다