Aller au contenu

Ajouter une base de données "Room"

5.1 Qu'est-ce qu'une base de données Room ?

  • Room est une couche de base de données au-dessus d'une base de données SQLite.
  • Room s'occupe des tâches banales que vous aviez l'habitude de gérer avec un SQLiteOpenHelper.
  • Room utilise le DAO pour émettre des requêtes vers sa base de données.
  • Par défaut, pour éviter de dégrader les performances de l'interface utilisateur, Room ne vous permet pas d'émettre des requêtes sur le thread principal. Lorsque les requêtes Room renvoient des LiveData ou sont déclarées avec suspend, elles sont automatiquement exécutées de manière asynchrone sur un thread d'arrière-plan.
  • Room fournit des vérifications au moment de la compilation des déclarations SQLite.

5.2 Implémenter la base de données Room

Votre classe de base de données Room doit être abstraite et hériter de RoomDatabase. En général, vous n'avez besoin que d'une seule instance d'une base de données Room pour toute l'application.

Créons-en une maintenant. Créez un fichier de classe appelé WordRoomDatabase sous le package data.db et ajoutez-y le code suivant :

data/db/WordRoomDatabase.kt
@Database(entities = [Word::class], version = 1, exportSchema = false)
abstract class WordRoomDatabase : RoomDatabase() {

    abstract fun wordDao(): WordDao

    companion object {
        @Volatile
        private var INSTANCE: WordRoomDatabase? = null

        fun getDatabase(context: Context): WordRoomDatabase {
            return INSTANCE ?: synchronized(this) {
                INSTANCE ?: Room.databaseBuilder(
                    context.applicationContext,
                    WordRoomDatabase::class.java,
                    "word_database"
                )
                    .fallbackToDestructiveMigration(dropAllTables = true)
                    .build()
                    .also { INSTANCE = it }
            }
        }
    }
}

Parcourons le code ensemble :

  • La classe de base de données pour Room doit être abstraite (abstract) et étendre RoomDatabase.
  • Vous annotez la classe pour qu'elle soit une base de données Room avec @Database et utilisez les paramètres d'annotation pour déclarer les entités qui appartiennent à la base de données (entities = [Word::class]) et définir le numéro de version. Chaque entité correspond à une table qui sera créée dans la base de données. Les migrations de base de données sont hors du champ d'application de ce codelab, nous définissons donc exportSchema à false ici pour éviter un avertissement de compilation. Dans une application réelle, vous devriez envisager de définir un répertoire que Room utilisera pour exporter le schéma afin que vous puissiez vérifier le schéma actuel dans votre système de contrôle de version.
  • La base de données expose des DAO via une fonction abstraite (wordDao()) pour chaque @Dao.
  • Nous avons défini un singleton, WordRoomDatabase, pour empêcher l'ouverture de plusieurs instances de la base de données en même temps. En Kotlin, il est placé dans un companion object, l'équivalent des membres statiques de Java.
  • getDatabase renvoie le singleton. Il créera la base de données la première fois qu'elle sera accédée, en utilisant le générateur de base de données de Room pour créer un objet RoomDatabase dans le contexte de l'application à partir de la classe WordRoomDatabase et le nommer "word_database".
  • L'opérateur ?: (opérateur Elvis) renvoie INSTANCE s'il existe déjà. Sinon, le bloc synchronized garantit qu'un seul thread crée la base, et @Volatile rend la valeur de INSTANCE immédiatement visible par tous les threads.
  • fallbackToDestructiveMigration(dropAllTables = true) : si le numéro de version change sans migration définie, Room supprime puis recrée toutes les tables.
  • Aucun ExecutorService n'est nécessaire : les fonctions suspend et les requêtes LiveData du DAO sont exécutées par Room sur un thread d'arrière-plan.

Migrations de base de données

Lorsque vous modifiez le schéma de la base de données, vous devez mettre à jour le numéro de version et définir une stratégie de migration.

Pour un échantillon, une stratégie de destruction et de re-création peut être suffisante. Mais, pour une application réelle, vous devez implémenter une stratégie de migration. Voir Understanding migrations with Room.

Erreurs de compilation

Dans Android Studio, si vous obtenez des erreurs lorsque vous collez du code ou pendant le processus de compilation, assurez-vous d'utiliser le nom complet du package pour les imports. Consultez Adding Components to your Project. Ensuite, sélectionnez Build > Clean Project, puis Build > Rebuild Project, et compilez à nouveau.

Si l'application plante au démarrage avec le message Cannot find implementation for ... WordRoomDatabase, le compilateur de Room n'a pas été exécuté : vérifiez le plugin ksp et la dépendance ksp(libs.room.compiler) de la tâche 1.