Миграция с SQLite на Room

Библиотека Room для работы с данными предоставляет ряд преимуществ по сравнению с прямым использованием API SQLite:

  • Проверка SQL-запросов на этапе компиляции
  • Удобные аннотации, минимизирующие повторяющийся и подверженный ошибкам шаблонный код.
  • Упрощенные пути миграции баз данных

Если в вашем приложении используется SQLite, отличный от Room, прочтите эту страницу, чтобы узнать, как перейти на Room. Если Room — это первая реализация SQLite в вашем приложении, см. раздел «Сохранение данных в локальной базе данных с помощью Room для базового использования».

Этапы миграции

Выполните следующие шаги для миграции вашей реализации SQLite в Room. Если ваша реализация SQLite использует большую базу данных или сложные запросы, вы можете предпочесть постепенную миграцию в Room. Дополнительную информацию о стратегии поэтапной миграции см. в разделе «Поэтапная миграция» .

Обновить зависимости

Для использования Room в вашем приложении необходимо добавить соответствующие зависимости в файл build.gradle вашего приложения. Дополнительную информацию о зависимостях Room см. в разделе «Настройка» .

Обновите классы модели для сущностей данных.

Room использует сущности данных для представления таблиц в базе данных. Каждый класс сущности представляет собой таблицу и имеет свойства, которые описывают столбцы в этой таблице. Выполните следующие шаги, чтобы обновить существующие классы моделей и сделать их сущностями Room:

  1. Добавьте аннотацию @Entity к объявлению класса, чтобы указать, что это сущность Room. При желании можно использовать свойство tableName , чтобы указать, что результирующая таблица должна иметь имя, отличное от имени класса.
  2. Добавьте аннотацию @PrimaryKey к свойству первичного ключа.
  3. Если имя какого-либо столбца в результирующей таблице должно отличаться от имени соответствующего свойства, добавьте к свойству аннотацию @ColumnInfo и установите свойство name на правильное имя столбца.
  4. Если у класса есть свойства, которые вы не хотите сохранять в базе данных, добавьте к ним аннотацию @Ignore чтобы указать, что Room не должен создавать для них столбцы в соответствующей таблице.
  5. Если у класса более одного конструктора, укажите, какой конструктор должен использовать Room, аннотировав все остальные конструкторы с помощью @Ignore .

@Entity(tableName = "users")
data class User(
    @PrimaryKey @ColumnInfo(name = "userid") val id: String,
    @ColumnInfo(name = "username") val userName: String?,
    @ColumnInfo(name = "last_update") val date: Date?,
)

Создание DAO

Room использует объекты доступа к данным (DAO) для определения функций, обращающихся к базе данных. Следуйте инструкциям в разделе «Доступ к данным с помощью DAO Room», чтобы заменить существующие функции запросов на DAO.

Создайте класс базы данных.

В реализациях Room для управления экземпляром базы данных используется класс базы данных. Ваш класс базы данных должен расширять RoomDatabase и ссылаться на все определенные вами сущности и DAO.

@Database(entities = [User::class], version = 2)
@ColumnTypeConverters(DateConverter::class)
abstract class UsersDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

Определите путь миграции

Поскольку номер версии базы данных меняется, необходимо определить объект Migration для сохранения существующих данных базы данных. Если схема базы данных не меняется, эта миграция может быть пустой.

val MIGRATION_1_2 = object : Migration(1, 2) {
    override suspend fun migrate(connection: SQLiteConnection) {
        // Empty implementation, because the schema isn't changing.
    }
}

Для получения дополнительной информации о путях миграции базы данных в Room см. раздел «Миграция базы данных» .

Обновите экземпляр базы данных.

После определения класса базы данных и пути миграции вы можете использовать Room.databaseBuilder для создания экземпляра вашей базы данных с примененным путем миграции:

val db =
    Room.databaseBuilder<UsersDatabase>(applicationContext, "database-name")
        .addMigrations(MIGRATION_1_2)
        .build()

Протестируйте свою реализацию.

Обязательно протестируйте новую реализацию Room:

Постепенная миграция

Если ваше приложение использует большую и сложную базу данных, одновременная миграция всего приложения в Room может оказаться нецелесообразной. Вместо этого вы можете на первом этапе реализовать сущности данных и базу данных Room, а затем перенести функции запросов в DAO.

Для реализации инкрементальной миграции получите обертку совместимости SupportSQLiteDatabase , используя функцию расширения roomDatabase.getSupportWrapper из артефакта androidx.room3:room3-sqlite-wrapper . Эта обертка позволяет выполнять прямые SQL-запросы в стиле Android к базе данных, управляемой Room, используя API Android SQLite:

// Get SupportSQLiteDatabase wrapper
val legacyDb = roomDatabase.getSupportWrapper()
legacyDb.execSQL("INSERT INTO users ...")