Номер не делает НЕ есть хорошо миграционная система, по крайней мере, пока 2.1.0-alpha03
.
Итак, пока у нас не будет более совершенной системы миграции, есть несколько обходных путей для упрощения миграции в комнате.
Поскольку не существует такого метода, как @Database(createNewTables = true)
или MigrationSystem.createTable(User::class)
, который должен быть тем или иным, единственно возможный способ - это запустить
CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))
внутри вашего migrate
метода.
val MIGRATION_1_2 = object : Migration(1, 2){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))")
}
}
Чтобы получить вышеуказанный сценарий SQL , у вас есть 4 способа
1. Напишите самостоятельно
По сути, вы должны написать приведенный выше сценарий, который будет соответствовать сценарию, который генерирует Room. Такой способ возможен, а не осуществлен. (Предположим, у вас есть 50 полей)
2. Схема экспорта
Если вы включите exportSchema = true
в свою @Database
аннотацию, Room создаст схему базы данных в / schemas папки вашего проекта. Использование
@Database(entities = [User::class], version = 2, exportSchema = true)
abstract class AppDatabase : RoomDatabase {
}
Убедитесь, что вы включили следующие строки в build.grade
свой модуль приложения
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas".toString())
}
}
Когда вы запустите или создадите проект, вы получите файл JSON 2.json
, который содержит все запросы в базе данных вашей комнаты.
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "325bd539353db508c5248423a1c88c03",
"entities": [
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
Итак, вы можете включить описанный выше метод createSql
в свой migrate
метод.
3. Получите запрос из AppDatabase_Impl
Если вы не хотите экспортировать схему, вы все равно можете получить запрос, запустив или построив проект, который будет генерировать AppDatabase_Impl.java
файл. и в пределах указанного файла вы можете иметь.
@Override
public void createAllTables(SupportSQLiteDatabase _db) {
_db.execSQL("CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))");
Внутри createAllTables
метода будут сценарии создания всех сущностей. Вы можете получить его и включить в свой migrate
метод.
4. Обработка аннотаций.
Как вы могли догадаться, Room генерирует все вышеперечисленное schema
, а также AppDatabase_Impl
файлы во время компиляции и с обработкой аннотаций, которую вы добавляете с помощью
kapt "androidx.room:room-compiler:$room_version"
Это означает, что вы также можете сделать то же самое и создать свою собственную библиотеку обработки аннотаций, которая генерирует все необходимые запросы на создание для вас.
Идея состоит в том, чтобы создать библиотеку обработки аннотаций для аннотаций комнат @Entity
и @Database
. Возьмем, @Entity
к примеру, класс, помеченный . Вот шаги, которые вам нужно будет выполнить
- Создайте новый
StringBuilder
и добавьте "СОЗДАТЬ ТАБЛИЦУ, ЕСЛИ НЕ СУЩЕСТВУЕТ"
- Получить имя таблицы из поля
class.simplename
или по tableName
полю @Entity
. Добавьте его в свойStringBuilder
- Затем для каждого поля вашего класса создайте столбцы SQL. Возьмите имя, тип, возможность обнуления поля либо по самому полю, либо по
@ColumnInfo
аннотации. Для каждого поля вы должны добавить id INTEGER NOT NULL
стиль столбца в ваш StringBuilder
.
- Добавить первичные ключи
@PrimaryKey
- Добавить
ForeignKey
иIndices
если существует.
- После завершения преобразуйте его в строку и сохраните в каком-нибудь новом классе, который вы хотите использовать. Например, сохраните его, как показано ниже
public final class UserSqlUtils {
public String createTable = "CREATE TABLE IF NOT EXISTS User (id INTEGER, PRIMARY KEY(id))";
}
Затем вы можете использовать его как
val MIGRATION_1_2 = object : Migration(1, 2){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(UserSqlUtils().createTable)
}
}
Я сделал для себя такую библиотеку, которую вы можете проверить и даже использовать в своем проекте. Обратите внимание, что созданная мной библиотека не заполнена и просто соответствует моим требованиям для создания таблиц.
RoomExtension для лучшей миграции
Приложение, использующее RoomExtension
Надеюсь, это было полезно.
ОБНОВИТЬ
На момент написания этого ответа версия комнаты была, 2.1.0-alpha03
и когда я написал разработчикам по электронной почте, я получил ответ
Ожидается, что в 2.2.0
К сожалению, у нас все еще отсутствует улучшенная система миграции.