Настройка 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() подходит только для разработки — в продакшене это потеря данных. Правильный путь: 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() в билдере — только для тестов, никогда для продакшна.
Один инстанс 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 дней. Стоимость рассчитывается индивидуально.







