Налаштування Room бази даних в Android-додатку
Room — це ORM-обгортка над SQLite від Google, частина Jetpack. Вона прибирає бойлерплейт ручного написання SQLiteOpenHelper, додає перевірку SQL-запитів в compile-time та нормально працює з coroutines та Flow. Налаштування Room — стандартна задача для будь-якого Android-додатку з локальним сховищем: кеш даних з сервера, оффлайн-режим, історія, чернетки.
Що входить в налаштування
Три компоненти: Entity (таблиця), DAO (інтерфейс запитів), Database (точка входу, спадкоємець RoomDatabase). Збірка через KSP (Kotlin Symbol Processing) — швидше, ніж KAPT, та це актуальна рекомендація Google з Room 2.5+.
@Entity з @PrimaryKey(autoGenerate = true), @ColumnInfo для переіменування колонок, @Embedded для вложених об'єктів, @Relation для зв'язків One-to-Many та Many-to-Many через @Junction. TypeConverter для кастомних типів — LocalDate, Instant, перечисління, JSON-поля.
DAO-інтерфейс: @Query, @Insert(onConflict = OnConflictStrategy.REPLACE), @Update, @Delete. Типи повернення: suspend fun для одноразових операцій, Flow<List<T>> для реактивних запитів, які автоматично переотправляють дані при зміні таблиці.
@Dao
interface ArticleDao {
@Query("SELECT * FROM articles WHERE categoryId = :id ORDER BY publishedAt DESC")
fun getByCategory(id: Long): Flow<List<Article>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(articles: List<Article>)
@Transaction
@Query("SELECT * FROM articles WHERE id = :id")
suspend fun getWithComments(id: Long): ArticleWithComments
}
@Transaction на запитах, що повертають об'єкти з @Relation — обов'язково, інакше дані можуть бути несогласованими при паралельних операціях.
Міграції схеми
fallbackToDestructiveMigration() підходить тільки для разработки — у production це втрата даних. Правильний шлях: addMigrations(MIGRATION_1_2, MIGRATION_2_3) з явним SQL для кожної зміни схеми. Room експортує JSON-схему (room.schemaLocation у build.gradle) — потрібно коммітити в репозиторій та тестувати міграції через MigrationTestHelper.
Тест міграції:
migrationTestHelper.runMigrationsAndValidate(
TEST_DB, 3, true, MIGRATION_1_2, MIGRATION_2_3
)
Без тестів міграцій перший же релиз із зміною схеми у частини користувачів викликає крах при відкритті додатку.
Часті помилки
Запити Room на main thread. За замовчуванням Room бросає виключення. allowMainThreadQueries() у білдері — тільки для тестів, ніколи для production.
Один інстанс Database. RoomDatabase — дорогостоящий об'єкт, створювати його потрібно один раз через synchronized синглтон або через Hilt з @Singleton. Кілька інстансів у паралельних coroutines — потенційна гонка даних.
Flow та lifecycle. Flow<T> з Room не має Android-специфіки — його потрібно збирати у viewModelScope з repeatOnLifecycle, а не у lifecycleScope напрямку, інакше collection продовжується в фоні.
Налаштування Room з базовою схемою, DAO, міграціями та unit-тестами: 2-3 дні. Складні схеми з множеством зв'язків та Full-Text Search через @Fts4 — до 5 днів. Вартість розраховується індивідуально.







