본문 바로가기

안드로이드/코틀린

[Android] Room 초기 데이터 설정

반응형

두가지 방법으로 초기 데이터를 설정할 수 있습니다.

1. addCallback이용

@Database(
    version = 1,
    entities = [Food.Item::class, Sort.Item::class, Category.Item::class]
)
abstract class DB: RoomDatabase() {

    abstract fun foodDao(): Food.Dao

    companion object{
        private val databaseName = "recommend.db"
        private var INSTANCE: DB? = null

        fun getInstance(context: Context): DB{

            return INSTANCE ?: synchronized(DB::class){
                INSTANCE ?: Room.databaseBuilder(
                    context.applicationContext,
                    DB::class.java,
                    databaseName
                ).createFromAsset("database/menu_recommend.db")
                    .addCallback(object : Callback(){

                    val initFoodList = mutableListOf(
                        Food.Item.create(context.getString(R.string.recommend_default_food_1), 3, 3),
                    )

                    override fun onCreate(db: SupportSQLiteDatabase) {
                        super.onCreate(db)

                        GlobalScope.launch {
                            withContext(Dispatchers.IO){
                                getInstance(context).run{
                                    // 음식 추가
                                    foodDao().insertAll(
                                        initFoodList
                                    )
                                }
                            }
                        }
                    }
                } )
                            .build().also { INSTANCE = it }
            }
        }

        fun destroyInstance(){
            INSTANCE = null
        }
    }
}

 

디비가 생성될때 insert하는 방식으로 최초 쿼리 실행시 onCreate 메소드가 호출됩니다.

그래서 특정 화면에서 의미 없는 쿼리를 실행해 실제 데이터를 보여주는 화면에서 빈화면이 노출되지 않도록 해야합니다.

데이터가 필요한 화면에서 최초 select문을 실행한다면 onCreate 호출 > select > 초기데이터 insert완료 순으로 호출됩니다.

 

2. db 파일 import

room 디비 구조와 동일한 디비 파일을 생성해 asset 폴더에 포함시켜 빌드하는 방법입니다.

경로

app > main > assets 

코드

@Database(
    version = 1,
    entities = [Food.Item::class, Sort.Item::class, Category.Item::class]
)
abstract class DB: RoomDatabase() {

    abstract fun foodDao(): Food.Dao

    companion object{
        private val databaseName = "recommend.db"
        private var INSTANCE: DB? = null

        fun getInstance(context: Context): DB{


            return INSTANCE ?: synchronized(DB::class){
                INSTANCE ?: Room.databaseBuilder(
                    context.applicationContext,
                    DB::class.java,
                    databaseName
                ).createFromAsset("menu_recommend.db").build().also { INSTANCE = it }
            }
        }

        fun destroyInstance(){
            INSTANCE = null
        }
    }
}

이 방법을 사용할 경우 디비를 create 하자마자 select을 해도 유저에게 데이터를 노출할수 있습니다.

 

데이터 테이블 비교 

코드로 작성한 테이블과 import하는 테이블의 타입이 동일해야 합니다.

non null 여부나 타입을 주의 해야하는데, 예로 Boolean으로 작성한 컬럼의 경우 실제 테이블은 int 타입으로 저장됩니다.

 

디비 테이블 생성 툴은 'DB Browser for SQLite'를 사용했습니다.

 

반응형