Quarto se não tiver um bom sistema de migração, pelo menos não até 2.1.0-alpha03
.
Portanto, até que tenhamos um sistema de migração melhor, existem algumas soluções alternativas para facilitar as migrações na sala.
Como não existe um método como @Database(createNewTables = true)
ou MigrationSystem.createTable(User::class)
, que deveria haver um ou outro, a única maneira possível é executando
CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))
dentro do seu migrate
método.
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`))")
}
}
Para obter o script SQL acima , você tem 4 maneiras
1. Escreva sozinho
Basicamente, você deve escrever o script acima que irá corresponder ao script gerado pela Room. Esse caminho é possível, não viável. (Considere que você tem 50 campos)
2. Esquema de exportação
Se você incluir exportSchema = true
em sua @Database
anotação, a Room irá gerar o esquema do banco de dados dentro de / schemas da pasta do seu projeto. O uso é
@Database(entities = [User::class], version = 2, exportSchema = true)
abstract class AppDatabase : RoomDatabase {
//...
}
Certifique-se de incluir as linhas abaixo no build.grade
módulo do seu aplicativo
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas".toString())
}
}
Ao executar ou construir o projeto, você obterá um arquivo JSON 2.json
, que contém todas as consultas no banco de dados do 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
},
Portanto, você pode incluir o acima createSql
dentro de seu migrate
método.
3. Obtenha a consulta de AppDatabase_Impl
Se você não quiser exportar o esquema, você ainda pode obter a consulta executando ou construindo o projeto que irá gerar o AppDatabase_Impl.java
arquivo. e dentro do arquivo especificado você pode ter.
@Override
public void createAllTables(SupportSQLiteDatabase _db) {
_db.execSQL("CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))");
Dentro do createAllTables
método, haverá os scripts de criação de todas as entidades. Você pode obtê-lo e incluí-lo em seu migrate
método.
4. Processamento de anotações.
Como você pode imaginar, o Room gera todos os itens mencionados acima schema
, e AppDatabase_Impl
arquivos dentro do tempo de compilação e com processamento de anotação que você adiciona com
kapt "androidx.room:room-compiler:$room_version"
Isso significa que você também pode fazer o mesmo e criar sua própria biblioteca de processamento de anotações que gera todas as consultas de criação necessárias para você.
A ideia é fazer uma biblioteca de processamento de anotações para anotações de Room @Entity
e @Database
. Pegue uma classe com anotações, @Entity
por exemplo. Estas são as etapas que você terá que seguir
- Faça um novo
StringBuilder
e anexe "CRIAR TABELA SE NÃO EXISTIR"
- Obtenha o nome da tabela de
class.simplename
ou por tableName
campo de @Entity
. Adicione ao seuStringBuilder
- Então, para cada campo de sua classe, crie colunas de SQL. Pegue o nome, tipo e nulidade do campo pelo próprio campo ou por
@ColumnInfo
anotação. Para cada campo, você deve adicionar o id INTEGER NOT NULL
estilo de uma coluna ao seu StringBuilder
.
- Adicionar chaves primárias por
@PrimaryKey
- Adicione
ForeignKey
e Indices
se existir.
- Após terminar, converta-o em string e salve-o em alguma nova classe que deseja usar. Por exemplo, salve como abaixo
public final class UserSqlUtils {
public String createTable = "CREATE TABLE IF NOT EXISTS User (id INTEGER, PRIMARY KEY(id))";
}
Então, você pode usá-lo como
val MIGRATION_1_2 = object : Migration(1, 2){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(UserSqlUtils().createTable)
}
}
Eu fiz uma biblioteca para mim que você pode conferir e até mesmo usar em seu projeto. Observe que a biblioteca que fiz não está cheia e apenas atende aos meus requisitos para a criação de tabelas.
RoomExtension para uma melhor migração
Aplicativo que usa RoomExtension
Espero que tenha sido útil.
ATUALIZAR
No momento em que escrevi esta resposta, a versão da sala era 2.1.0-alpha03
e quando enviei um e-mail aos desenvolvedores, recebi uma resposta de
Espera-se que haja um melhor sistema de migração em 2.2.0
Infelizmente, ainda não temos um sistema de migração melhor.