Effectuer une migration de SQLite vers Room

La bibliothèque de persistance Room offre de nombreux avantages en comparaison avec l'utilisation directe des API SQLite :

  • Une vérification des requêtes SQL au moment de la compilation.
  • Des annotations pratiques qui réduisent le code récurrent qui peut s'avérer répétitif et être sujet aux erreurs.
  • Des chemins de migration simplifiés pour les bases de données.

Si votre application dispose d'une implémentation SQLite sans Room, consultez cette page pour découvrir comment migrer vers Room. Si Room est la première implémentation de SQLite dans votre application, consultez la section Enregistrer des données dans une base de données locale à l'aide de Room pour obtenir des informations de base sur l'utilisation.

Procédure de migration

Pour migrer votre implémentation de SQLite vers Room, procédez comme suit : Si votre implémentation de SQLite utilise une base de données volumineuse ou des requêtes complexes, vous pouvez choisir une migration progressive vers Room. Pour en savoir plus sur une stratégie de migration par incréments, consultez la section Migration par incréments.

Mettre à jour les dépendances

Pour utiliser Room dans votre application, vous devez inclure les dépendances appropriées dans le fichier build.gradle de votre application. Pour en savoir plus sur les dépendances Room, consultez la section Configuration.

Convertir les classes de modèle en entités de données

Room utilise des entités de données pour représenter les tables de la base de données. Chaque classe d'entité représente une table et comporte des propriétés qui représentent les colonnes de cette table. Procédez comme suit pour convertir vos classes de modèle existantes en entités Room :

  1. Annotez la déclaration de classe avec @Entity pour indiquer qu'il s'agit d'une entité Room. Vous pouvez éventuellement utiliser la propriété tableName pour indiquer que la table obtenue doit porter un nom différent de celui de la classe.
  2. Annotez la propriété de clé primaire avec @PrimaryKey.
  3. Si l'une des colonnes de la table obtenue doit porter un nom différent de celui de la propriété correspondante, annotez la propriété avec @ColumnInfo et définissez la propriété name sur le nom de colonne approprié.
  4. Si la classe comporte des propriétés que vous ne souhaitez pas conserver dans la base de données, annotez-les avec @Ignore afin d'indiquer que Room ne doit pas créer de colonnes pour ces propriétés dans la table correspondante.
  5. Si la classe comporte plusieurs constructeurs, indiquez quel constructeur Room doit utiliser en annotant tous les autres constructeurs avec @Ignore.

@Entity(tableName = "users")
data class User(
    @PrimaryKey @ColumnInfo(name = "userid") val id: String,
    @ColumnInfo(name = "username") val userName: String?,
    @ColumnInfo(name = "last_update") val date: Date?,
)

Créer des DAO

Room utilise des objets d'accès aux données (DAO) pour définir les fonctions qui accèdent à la base de données. Suivez les conseils de la section Accéder aux données à l'aide des DAO de Room pour remplacer vos fonctions de requête existantes par des DAO.

Créer une classe de base de données

Les implémentations de Room utilisent une classe de base de données pour gérer une instance de la base de données. Votre classe de base de données doit étendre RoomDatabase et référencer l'ensemble des entités et des DAO que vous avez définis.

@Database(entities = [User::class], version = 2)
@ColumnTypeConverters(DateConverter::class)
abstract class UsersDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

Définir un chemin de migration

Étant donné que le numéro de version de la base de données évolue, vous devez définir un Migration objet pour conserver les données existantes dans la base de données. Si le schéma de la base de données ne change pas, cette migration peut être vide.

val MIGRATION_1_2 = object : Migration(1, 2) {
    override suspend fun migrate(connection: SQLiteConnection) {
        // Empty implementation, because the schema isn't changing.
    }
}

Pour en savoir plus sur les chemins de migration de base de données dans Room, consultez la section Migrer votre base de données.

Mettre à jour l'instanciation de la base de données

Après avoir défini une classe de base de données et un chemin de migration, vous pouvez utiliser Room.databaseBuilder pour créer une instance de votre base de données avec le chemin de migration appliqué :

val db =
    Room.databaseBuilder<UsersDatabase>(applicationContext, "database-name")
        .addMigrations(MIGRATION_1_2)
        .build()

Tester l'implémentation

Veillez à tester votre nouvelle implémentation de Room :

Migration par incréments

Si votre application utilise une base de données volumineuse et complexe, vous ne pourrez peut-être pas migrer votre application vers Room en une seule fois. À la place, vous pouvez éventuellement implémenter les entités de données et la base de données Room dans un premier temps, puis migrer vos fonctions de requête vers des DAO ultérieurement.

Pour implémenter une migration par incréments, obtenez un wrapper de compatibilité SupportSQLiteDatabase à l'aide de la fonction d'extension roomDatabase.getSupportWrapper de l'artefact androidx.room3:room3-sqlite-wrapper. Ce wrapper vous permet d'exécuter des requêtes SQL directes de style Android sur la base de données gérée par Room à l'aide des API Android SQLite :

// Get SupportSQLiteDatabase wrapper
val legacyDb = roomDatabase.getSupportWrapper()
legacyDb.execSQL("INSERT INTO users ...")