Enregistrer des données dans une base de données locale à l'aide de Room   Fait partie d'Android Jetpack.

Essayer avec Kotlin Multiplatform
Kotlin Multiplatform permet de partager la couche de base de données avec d'autres plates-formes. Découvrez comment configurer et utiliser une base de données Room dans KMP.

La persistance de données structurées en local peut s'avérer particulièrement bénéfique pour les applications qui gèrent ces données en très grandes quantités. Le cas d'utilisation le plus courant consiste à mettre en cache les éléments de données pertinents de sorte que, lorsque l'appareil ne peut pas accéder au réseau, vos utilisateurs puissent continuer à parcourir ce contenu hors connexion.

La bibliothèque de persistance Room fournit une couche d'abstraction sur SQLite afin de permettre un accès fluide à la base de données, tout en exploitant toute la puissance de SQLite. Room offre, en particulier, les avantages suivants :

  • 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.

Nous vous recommandons d'utiliser Room plutôt que d'utiliser directement les API SQLite.

Configuration

Pour utiliser Room dans votre application, ajoutez les dépendances suivantes au fichier build.gradle.kts de votre module. Room 3.0 nécessite KSP pour le traitement des annotations.

Kotlin

dependencies {
    val room_version = "3.0.0"

    implementation("androidx.room3:room3-runtime:$room_version")
    ksp("androidx.room3:room3-compiler:$room_version")
}

Groovy

dependencies {
    def room_version = "3.0.0"

    implementation "androidx.room3:room3-runtime:$room_version"

    ksp "androidx.room3:room3-compiler:$room_version"
}

Composants principaux

Room repose sur trois composants principaux :

  • La classe de base de données qui contient la base de données et sert de point d'accès principal pour la connexion sous-jacente aux données persistantes de votre application.
  • Les entités de données qui représentent les tables de la base de données de votre application.
  • Les objets d'accès aux données (DAO) qui fournissent des fonctions que votre application peut utiliser pour interroger, mettre à jour, insérer et supprimer des données dans la base de données.

La classe de base de données fournit à votre application des instances des DAO associés à cette base de données. L'application peut ensuite utiliser ces DAO pour récupérer des données de la base de données en tant qu'instances des objets d'entité associés. L'application peut également utiliser les entités de données définies pour mettre à jour des lignes dans les tables correspondantes ou pour créer des lignes à insérer. La figure 1 illustre la relation entre les différents composants de Room.

Figure 1. Schéma de l'architecture de la bibliothèque Room.

Exemple d'implémentation

Cette section présente un exemple d'implémentation d'une base de données Room avec une seule entité de données et un seul DAO.

Entité de données

Le code suivant définit une entité de données User. Chaque instance de User représente une ligne dans une table user de la base de données de l'application.

@Entity
data class User(
    @PrimaryKey val uid: Int,
    @ColumnInfo(name = "first_name") val firstName: String,
    @ColumnInfo(name = "last_name") val lastName: String
)

Pour en savoir plus sur les entités de données dans Room, consultez Définir des données à l'aide d'entités Room.

Objet d'accès aux données (DAO)

Le code suivant définit un DAO appelé UserDao. UserDao fournit les fonctions que le reste de l'application utilise pour interagir avec les données de la table user.

@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    suspend fun getAll(): List<User>

    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    suspend fun loadAllByIds(userIds: IntArray): List<User>

    @Query(
        """
        SELECT * FROM user
        WHERE first_name LIKE :first AND last_name LIKE :last LIMIT 1
        """
    )
    suspend fun findByName(first: String, last: String): User

    @Insert
    suspend fun insertAll(vararg users: User)

    @Delete
    suspend fun delete(user: User)
}

Pour en savoir plus sur les DAO, consultez Accéder aux données avec les DAO de Room.

Base de données

Le code suivant définit une classe AppDatabase destinée à contenir la base de données. AppDatabase définit la configuration de la base de données et sert de point d'accès principal de l'application aux données persistantes. La classe de base de données doit remplir les conditions suivantes :

  • La classe doit comporter une annotation @Database qui inclut un tableau entities listant toutes les entités de données associées à la base de données.
  • La classe doit être une classe abstraite qui étend RoomDatabase.
  • Pour chaque classe DAO associée à la base de données, la classe de base de données doit définir une fonction abstraite qui ne comporte aucun argument et qui renvoie une instance de la classe DAO.

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

Remarque : Si votre application s'exécute dans un seul processus, vous devez suivre le patron de conception Singleton lors de l'instanciation d'un objet AppDatabase. Chaque instance RoomDatabase est assez coûteuse en ressources, et vous aurez rarement besoin d'accéder à plusieurs instances au cours d'un même processus.

Si votre application s'exécute dans plusieurs processus, incluez enableMultiInstanceInvalidation() dans votre appel du compilateur de base de données. Ainsi, lorsque vous aurez une instance de AppDatabase dans chaque processus, vous pourrez invalider le fichier de base de données partagé dans un processus et cette invalidation sera automatiquement propagée aux instances de AppDatabase dans les autres processus.

Utilisation

Après avoir défini l'entité de données, le DAO et l'objet de base de données, vous pouvez utiliser le code suivant pour créer une instance de la base de données :

val db =
    Room.databaseBuilder<AppDatabase>(applicationContext, "database-name")
        .setDriver(AndroidSQLiteDriver())
        .build()

Vous pourrez ensuite utiliser les fonctions abstraites de la classe AppDatabase pour obtenir une instance du DAO. Vous pourrez ensuite utiliser les fonctions de l'instance DAO pour interagir avec la base de données :

val userDao = db.userDao()
val users: List<User> = userDao.getAll()

Ressources supplémentaires

Pour en savoir plus sur Room, consultez les ressources supplémentaires suivantes :

Exemples