La salle n'a PAS un bon système de migration, du moins pas avant 2.1.0-alpha03
.
Donc, jusqu'à ce que nous ayons un meilleur système de migration, il existe des solutions de contournement pour avoir des migrations faciles dans la salle.
Comme il n'y a pas de méthode telle que @Database(createNewTables = true)
ou MigrationSystem.createTable(User::class)
, qu'il devrait y avoir l'une ou l'autre, la seule façon possible est d'exécuter
CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))
à l'intérieur de votre migrate
méthode.
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`))")
}
}
Afin d'obtenir au-dessus du script SQL , vous avez 4 façons
1. Écrivez par vous-même
Fondamentalement, vous devez écrire le script ci-dessus qui correspondra au script généré par Room. Cette manière est possible, pas faisable. (Considérez que vous avez 50 champs)
2. Exporter le schéma
Si vous incluez exportSchema = true
dans votre @Database
annotation, Room générera un schéma de base de données dans / schemas de votre dossier de projet. L'utilisation est
@Database(entities = [User::class], version = 2, exportSchema = true)
abstract class AppDatabase : RoomDatabase {
//...
}
Assurez-vous que vous avez inclus les lignes ci-dessous dans build.grade
votre module d'application
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas".toString())
}
}
Lorsque vous exécutez ou générez le projet, vous obtiendrez un fichier JSON contenant 2.json
toutes les requêtes de votre base de données 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
},
Ainsi, vous pouvez inclure ce qui précède createSql
dans votre migrate
méthode.
3. Obtenir une requête depuis AppDatabase_Impl
Si vous ne souhaitez pas exporter le schéma, vous pouvez toujours obtenir la requête en exécutant ou en créant le projet qui générera le AppDatabase_Impl.java
fichier. et dans le fichier spécifié, vous pouvez avoir.
@Override
public void createAllTables(SupportSQLiteDatabase _db) {
_db.execSQL("CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))");
Dans la createAllTables
méthode, il y aura les scripts de création de toutes les entités. Vous pouvez l'obtenir et l'inclure dans votre migrate
méthode.
4. Traitement des annotations.
Comme vous pouvez le deviner, Room génère tous les fichiers mentionnés ci-dessus schema
et les AppDatabase_Impl
fichiers dans le temps de compilation et avec le traitement d'annotation que vous ajoutez avec
kapt "androidx.room:room-compiler:$room_version"
Cela signifie que vous pouvez également faire de même et créer votre propre bibliothèque de traitement d'annotations qui génère toutes les requêtes de création nécessaires pour vous.
L'idée est de créer une bibliothèque de traitement des annotations pour les annotations de salle de @Entity
et @Database
. Prenons par exemple une classe annotée @Entity
. Voici les étapes que vous devrez suivre
- Créez un nouveau
StringBuilder
et ajoutez "CREATE TABLE IF NOT EXISTS"
- Obtenez le nom de la table à partir
class.simplename
ou par tableName
champ de @Entity
. Ajoutez-le à votreStringBuilder
- Ensuite, pour chaque champ de votre classe, créez des colonnes de SQL. Prenez le nom, le type, la nullité du champ soit par le champ lui-même, soit par
@ColumnInfo
annotation. Pour chaque champ, vous devez ajouter le id INTEGER NOT NULL
style d'une colonne à votre StringBuilder
.
- Ajouter des clés primaires par
@PrimaryKey
- Ajouter
ForeignKey
et Indices
s'il existe.
- Après avoir terminé, convertissez-le en chaîne et enregistrez-le dans une nouvelle classe que vous souhaitez utiliser. Par exemple, enregistrez-le comme ci-dessous
public final class UserSqlUtils {
public String createTable = "CREATE TABLE IF NOT EXISTS User (id INTEGER, PRIMARY KEY(id))";
}
Ensuite, vous pouvez l'utiliser comme
val MIGRATION_1_2 = object : Migration(1, 2){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(UserSqlUtils().createTable)
}
}
J'ai créé une telle bibliothèque pour moi-même que vous pouvez consulter et même l'utiliser dans votre projet. Notez que la bibliothèque que j'ai créée n'est pas pleine et qu'elle répond simplement à mes exigences pour la création de table.
RoomExtension pour une meilleure migration
Application qui utilise RoomExtension
J'espère que c'était utile.
METTRE À JOUR
Au moment d'écrire cette réponse, la version de la salle était 2.1.0-alpha03
et quand j'ai envoyé un e-mail aux développeurs, j'ai reçu une réponse de
Il est prévu d'avoir un meilleur système de migration dans 2.2.0
Malheureusement, il nous manque encore un meilleur système de migration.