Как добавить в Room сразу список из нескольких элементов?

При работе с Room, чтобы добавить список нескольких элементов, необходимо использовать асинхронные операции. Для этого можно воспользоваться Coroutine или RxJava, но в данном ответе рассмотрим вариант с использованием Coroutine.

1. Для начала, у вас должны быть установлены необходимые зависимости. В файле build.gradle вашего модуля добавьте следующие строки:

dependencies {
    def room_version = "2.3.0"

    // Добавляем зависимости для Room
    implementation "androidx.room:room-runtime:$room_version"
    kapt "androidx.room:room-compiler:$room_version"
    implementation "androidx.room:room-ktx:$room_version"
}

2. Создайте класс, который представляет вашу сущность (Entity) и аннотируйте его аннотацией @Entity. Например:

@Entity(tableName = "items")
data class Item(
    @PrimaryKey val id: Int,
    val name: String
)

3. Создайте интерфейс для работы с базой данных. Аннотируйте этот интерфейс аннотацией @Dao. В интерфейсе объявите метод для добавления списка элементов. Например:

@Dao
interface ItemDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertItems(items: List<Item>)
}

4. Создайте абстрактный класс, который расширяет RoomDatabase. Аннотируйте этот класс аннотацией @Database и укажите сущности, которые он содержит (в нашем случае это только Item). Например:

@Database(entities = [Item::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun itemDao(): ItemDao

    companion object {
        @Volatile
        private var instance: AppDatabase? = null

        fun getInstance(context: Context): AppDatabase {
            return instance ?: synchronized(this) {
                instance ?: buildDatabase(context).also { instance = it }
            }
        }

        private fun buildDatabase(context: Context): AppDatabase {
            return Room.databaseBuilder(context, AppDatabase::class.java, "my-database")
                .build()
        }
    }
}

5. Теперь вы можете использовать метод insertItems() для добавления списка элементов в базу данных. Пример использования:

val items = listOf(
    Item(1, "Item 1"),
    Item(2, "Item 2"),
    Item(3, "Item 3")
)

val database = AppDatabase.getInstance(context)
database.itemDao().insertItems(items)

Все операции, связанные с базой данных, включая добавление списка элементов, должны выполняться внутри suspend функций или Coroutine. В примере выше мы использовали suspend функцию insertItems(), которая будет выполняться асинхронно и должна вызываться из другой suspend функции или из блока Coroutine.

Важно отметить, что при использовании Room список элементов будет добавлен атомарно. Если какой-либо элемент из списка уже существует в базе данных, он будет заменен на новый элемент с тем же ключом. Это управляется параметром onConflict аннотации @Insert, установленным в значение OnConflictStrategy.REPLACE в нашем примере.