Camera non non hanno una buona migrazione del sistema, almeno non fino a quando 2.1.0-alpha03
.
Quindi, finché non avremo un sistema di migrazione migliore, ci sono alcune soluzioni alternative per avere migrazioni facili nella stanza.
Poiché non esiste un metodo come @Database(createNewTables = true)
o MigrationSystem.createTable(User::class)
, che dovrebbe esserci l'uno o l'altro, l'unico modo possibile è correre
CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))
all'interno del tuo migrate
metodo.
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`))")
}
}
Per ottenere lo script SQL superiore , hai 4 modi
1. Scrivi da solo
Fondamentalmente, devi scrivere lo script sopra che corrisponderà allo script generato da Room. In questo modo è possibile, non fattibile. (Considera di avere 50 campi)
2. Esporta schema
Se includi exportSchema = true
all'interno @Database
dell'annotazione, Room genererà lo schema del database all'interno di / schemas della cartella del tuo progetto. L'utilizzo è
@Database(entities = [User::class], version = 2, exportSchema = true)
abstract class AppDatabase : RoomDatabase {
//...
}
Assicurati di aver incluso le seguenti righe nel build.grade
modulo dell'app
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas".toString())
}
}
Quando esegui o crei il progetto otterrai un file JSON 2.json
, che contiene tutte le query all'interno del tuo database 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
},
Quindi, puoi includere quanto sopra createSql
dentro di temigrate
metodo.
3. Ottieni query da AppDatabase_Impl
Se non vuoi esportare lo schema puoi comunque ottenere la query eseguendo o costruendo il progetto che genererà il AppDatabase_Impl.java
file. e all'interno del file specificato puoi avere.
@Override
public void createAllTables(SupportSQLiteDatabase _db) {
_db.execSQL("CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))");
All'interno del createAllTables
metodo, ci saranno gli script di creazione di tutte le entità. Puoi ottenerlo e includerlo dentro di temigrate
metodo.
4. Elaborazione delle annotazioni.
Come puoi immaginare, Room genera tutto quanto sopra menzionato schema
e AppDatabase_Impl
file entro il tempo di compilazione e con Elaborazione annotazioni che aggiungi con
kapt "androidx.room:room-compiler:$room_version"
Ciò significa che puoi anche fare lo stesso e creare la tua libreria di elaborazione delle annotazioni che genera tutte le query di creazione necessarie per te.
L'idea è di creare una libreria di elaborazione delle annotazioni per le annotazioni Room di @Entity
e @Database
. Prendi una classe che è annotata con @Entity
per esempio. Questi sono i passaggi che dovrai seguire
- Creane uno nuovo
StringBuilder
e aggiungi "CREA TABELLA SE NON ESISTE"
- Ottieni il nome della tabella da
class.simplename
o per tableName
campo di @Entity
. Aggiungilo al tuoStringBuilder
- Quindi per ogni campo della tua classe crea colonne di SQL. Prendi il nome, il tipo, il nullability del campo dal campo stesso o
@ColumnInfo
dall'annotazione. Per ogni campo, devi aggiungere lo id INTEGER NOT NULL
stile di una colonna al tuo fileStringBuilder
.
- Aggiungi chiavi primarie di
@PrimaryKey
- Aggiungi
ForeignKey
eIndices
se esiste.
- Dopo aver finito convertilo in stringa e salvalo in una nuova classe che desideri utilizzare. Ad esempio, salvalo come di seguito
public final class UserSqlUtils {
public String createTable = "CREATE TABLE IF NOT EXISTS User (id INTEGER, PRIMARY KEY(id))";
}
Quindi puoi usarlo come
val MIGRATION_1_2 = object : Migration(1, 2){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(UserSqlUtils().createTable)
}
}
Ho creato una libreria del genere per me stesso che puoi controllare e persino usarla nel tuo progetto. Nota che la libreria che ho creato non è piena e soddisfa solo i miei requisiti per la creazione di tabelle.
RoomExtension per una migliore migrazione
Applicazione che utilizza RoomExtension
Spero sia stato utile.
AGGIORNARE
Al momento della stesura di questa risposta, la versione room era 2.1.0-alpha03
e quando ho inviato un'email agli sviluppatori ho ricevuto una risposta
Si prevede di avere un sistema di migrazione migliore in 2.2.0
Purtroppo, ci manca ancora un sistema di migrazione migliore.