fbpx

Добавление записи в БД используя Room

В данный момент в нашей БД нет данных. Мы рассмотрим добавление данных двумя способами: добавим часть данных вручную, открыв соединение с базой данных, а второй – создадим Activity для добавления новых слов. Для удаления всех данных и заполнения базы данных записями, мы создадим RoomDatabase.Callback  и переопределим метод onOpen(). Кроме того, так как по умолчанию Room не позволяет обращаться к базе данных в главном потоке, onOpen() использует корутины для фоновой работы.

Чтобы запустить работу в фоновом потоке нам необходим CoroutineScope Обновите метод getDatabase в классе WordRoomDatabase чтобы передать скоуп в качестве параметра:

fun getDatabase(
       context: Context,
       scope: CoroutineScope
  ): WordRoomDatabase {
...
}

Также не забудьте обновить блок init в WordViewModel для того, чтобы тоже передать скоуп:

val wordsDao = WordRoomDatabase.getDatabase(application, viewModelScope).wordDao()

Для наполнения БД записями, необходимо реализовать RoomDatabase.Callback() который также принимает CoroutineScope  в качестве аргумента в конструкторе. После этого, необходимо переопределить метод onOpen  для заполнения базы данных записями.

private class WordDatabaseCallback(
    private val scope: CoroutineScope
) : RoomDatabase.Callback() {

    override fun onOpen(db: SupportSQLiteDatabase) {
        super.onOpen(db)
        INSTANCE?.let { database ->
            scope.launch {
                populateDatabase(database.wordDao())
            }
        }
    }

    suspend fun populateDatabase(wordDao: WordDao) {
        // Delete all content here.
        wordDao.deleteAll()

        // Add sample words.
        var word = Word("Hello")
        wordDao.insert(word)
        word = Word("World!")
        wordDao.insert(word)

        // TODO: Add your own words!
    }
}

После этого, добавьте реализованный колбэк в метод создания экземпляра базы данных

.addCallback(WordDatabaseCallback(scope))

В итоге мы должны получить такой код:

@Database(entities = arrayOf(Word::class), version = 1, exportSchema = false)
abstract class WordRoomDatabase : RoomDatabase() {

   abstract fun wordDao(): WordDao

   private class WordDatabaseCallback(
       private val scope: CoroutineScope
   ) : RoomDatabase.Callback() {

       override fun onOpen(db: SupportSQLiteDatabase) {
           super.onOpen(db)
           INSTANCE?.let { database ->
               scope.launch {
                   var wordDao = database.wordDao()

                   // Delete all content here.
                   wordDao.deleteAll()

                   // Add sample words.
                   var word = Word("Hello")
                   wordDao.insert(word)
                   word = Word("World!")
                   wordDao.insert(word)

                   // TODO: Add your own words!
                   word = Word("TODO!")
                   wordDao.insert(word)
               }
           }
       }
   }

   companion object {
       @Volatile
       private var INSTANCE: WordRoomDatabase? = null

       fun getDatabase(
           context: Context,
           scope: CoroutineScope
       ): WordRoomDatabase {
            // if the INSTANCE is not null, then return it,
            // if it is, then create the database
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                        context.applicationContext,
                        WordRoomDatabase::class.java,
                        "word_database"
                )
                 .addCallback(WordDatabaseCallback(scope))
                 .build()
                INSTANCE = instance
                // return instance
                instance
        }
   }
}

Осталось совсем немного! В следующем уроке мы создадим activity, которая будет уметь добавлять новые слова в БД.