Ответ 1
Комната НЕ имеет хорошей Миграционной Системы, по крайней мере, до 2.1.0-alpha03
.
Ожидается, что лучшая система миграции в
2.2.0
Таким образом, пока у нас нет лучшей Миграционной системы, есть несколько обходных путей для легкой миграции в комнате.
Поскольку нет такого метода, как @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 сгенерирует схему базы данных в /@Database
папки вашего проекта. Использование
@Database(entities = [User::class], version = 2, exportSchema = true)
abstract class AppDatabase : RoomDatabase {
//...
}
Убедитесь, что вы включили следующие строки в build.grade
вашего модуля приложения
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas".toString())
}
}
Когда вы запустите или 2.json
проект, вы получите файл JSON 2.json
, в котором есть все запросы в вашей базе данных Room.
"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
проект, который сгенерирует файл 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
Надеюсь, это было полезно.