Maintenant que nous avons des interfaces DAO, nous allons pouvoir utiliser les annotations proposées par Room pour que l’ORM puisse les utiliser et réaliser les bonnes opérations sur la base de données SQLite.
Définir les interfaces avec l’annotation@Dao
La première annotation que nous allons utiliser est l’annotation@Dao
. Il s’agit d’un élément essentiel de la bibliothèque Room qui permet de définir des interfaces comme des DAO. Cette annotation est portée directement par l’interface que l’on souhaite définir en tant que Dao.
Si vous utilisez Java : | Si vous utilisez Kotlin : |
|
|
Insérez une donnée avec l’annotation @Insert
Comme vous le savez, le concept de CRUD est au cœur de Room. Pour chacune des opérations, il existe une annotation Room à utiliser. Débutons avec la première opération représentée par le “C” : Create.
Créer, c’est en réalité insérer une ligne dans la base de données. L’annotation, portée par une méthode de l’interface, qui permet d’indiquer que ladite méthode est destinée à insérer une ou plusieurs lignes dans la base de données est@Insert
.
Dans le cadre de la fonctionnalité développée pour l’application PETiSoin, deux méthodes vont porter cette annotation :insertAnimal
etinsertNote
.
Si vous utilisez Java : | Si vous utilisez Kotlin : |
|
|
En SQL, lors de l’insertion d’une ligne dans la base de données relationnelle, il peut se produire des conflits. C’est par exemple le cas lorsque l’on tente d’insérer une ligne dont la clé primaire est déjà présente dans la base de données. Dans Room si un tel cas se produit, l’insertion va simplement échouer par défaut.
Room offre alors la possibilité de personnaliser son comportement face à de telles situations. En cas de conflit lors de l’insertion d’une ligne dans la base de données, l’attribut onConflict
, de l’annotation @Insert
qui permet de personnaliser le comportement de Room. Les valeurs possibles pour cet attribut et le comportement de Room sont détaillés dans ce tableau.
Valeur | Comportement en cas de conflit |
| L’insertion est annulée et l’ensemble de la transaction est annulé. |
| L’insertion est annulée mais le reste de la transaction se poursuit. |
| L’insertion remplace la ligne avec laquelle elle est en conflit. |
Illustrons l’utilisation de la stratégie OnConflictStrategy.REPLACE
sur les interfaces AnimalDao
etNoteDao
.
Si vous utilisez Java : | Si vous utilisez Kotlin : |
|
|
Sélectionnez une donnée avec l’annotation@Query
Continuons l’exploration des lettres qui composent le mot CRUD avec la lettre “R” : Read.
Lire, c’est en réalité sélectionner une ou plusieurs lignes de la base de données répondant à un ou plusieurs critères que vous pouvez définir en tant que développeur. Pour sélectionner des lignes dans la base de données, l’annotation à utiliser est@Query
.
L’annotation @Read
n’existe pas ?
Effectivement, l’annotation @Read
, bien que logique, n’existe pas. En réalité, si l’on doit utiliser l’annotation@Query
c’est que pour sélectionner les lignes qui vous intéressent, il convient d’écrire des requêtes SQL en tant qu’unique attribut de l’annotation.
Dans le cadre de la fonctionnalité développée pour l’application PETiSoin, plusieurs méthodes vont porter cette annotation :getAnimalById
, getAllAnimals
, getNoteById
et getAllNotesByAnimalId
.
Si vous utilisez Java : | Si vous utilisez Kotlin : |
|
|
Mettez à jour une donnée avec l’annotation@Update
Continuons l’exploration des lettres qui composent le mot CRUD avec la lettre “U” : Update.
Mettre à jour, c’est en réalité modifier une ligne qui est déjà présente dans la base de données. Notez que dans ce cas la clé primaire associée à la ligne ne change pas. Si cette clé était modifiée, cela reviendrait à créer une nouvelle ligne. La méthode de l’interface porte l’annotation qui se nomme @Update
. Cette dernière est destinée à supprimer une ou plusieurs lignes dans la base de données.
Dans le cadre de la fonctionnalité développée pour l’application PETiSoin, deux méthodes vont porter cette annotation :updateAnimal
etupdateNote
.
Si vous utilisez Java : | Si vous utilisez Kotlin : |
|
|
À l’image des insertions de données, la mise à jour d’une ligne dans la base de données relationnelle peut entraîner des conflits. Dans Room, si un tel cas se produit, la mise à jour va simplement échouer par défaut. L’attributonConflict
permet alors de gérer ce genre de situation. Les valeurs possibles pour cet attribut et le comportement de Room sont détaillés dans ce tableau.
Valeur | Comportement en cas de conflit |
| La mise à jour est annulée et l’ensemble de la transaction est annulé. |
| La mise à jour est annulée mais le reste de la transaction se poursuit. |
| La mise à jour remplace la ligne avec laquelle elle est en conflit. |
Illustrons l’utilisation de la stratégieOnConflictStrategy.REPLACE
sur les interfacesAnimalDao
et NoteDao
.
Si vous utilisez Java : | Si vous utilisez Kotlin : |
|
|
Insérez ou mettez à jour une donnée avec l’annotation @Upsert
Les annotations que nous avons vues jusqu’à maintenant couvrent des scénarios simples et notamment l’insertion et la mise à jour. Mais elles ne répondent pas au scénario suivant : insérer ou mettre à jour. C’est pour répondre à ce besoin que l’annotation@Upsert
a été introduite dans la version 2.5.0 de Room. L'objectif principal de cette annotation est de combiner les opérations d'insertion et de mise à jour en une seule instruction, simplifiant ainsi le code et améliorant l'efficacité des opérations sur la base de données.
Utiliser l’annotation@Insert
avec la stratégie de conflitOnConflictStrategy.REPLACE
ne permet-elle pas de répondre à ce besoin ?
Sur le papier effectivement, mais dans les faits, c’est un peu plus subtil que ça. Lors de la requête d’insertion, s’il y a un conflit, Room ne va pas réellement mettre à jour la ou les lignes concernées. Il va en réalité les supprimer de la base de données pour insérer les nouvelles. Cette façon de faire peut être à l’origine d’effets de bord. Par exemple, si la ligne supprimée a des informations qui ne sont pas fournies par la nouvelle insertion (par exemple, des colonnes non nulles ou des champs non fournis dans l'objet inséré), ces informations seront perdues.
C’est pour répondre à ce besoin que Room permet d’utiliser l’annotation@Upsert
. Illustrons son utilisation sur les interfacesAnimalDao
et NoteDao
.
Si vous utilisez Java : | Si vous utilisez Kotlin : |
|
|
Supprimez une donnée avec l’annotation@Delete
Après le “U” de CRUD, attaquons nous maintenant à la dernière lettre “D” : Delete.
Dans le cadre d’une base de données relationnelle, supprimer, c’est supprimer une ligne dans la base de données. La méthode de l’interface porte l’annotation qui se nomme@Delete
. Cette dernière est destinée à supprimer une ou plusieurs lignes dans la base de données.
Dans le cadre de la fonctionnalité développée pour l’application PETiSoin, deux méthodes vont porter cette annotation :deleteAnimal
etdeleteNote
.
Si vous utilisez Java : | Si vous utilisez Kotlin : |
|
|
Voici une vidéo qui récapitule les principales étapes pour intégrer et annoter des DAO.
À vous de jouer !
Contexte
Vous devez continuer l’implémentation technique de la rubrique “Santé” de l’application PETiSoin, en vous attaquant aux DAOs.
Dans le projet, disponible sur GitHub (Java ou Kotlin), les interfaces DAOAnimalDao
et VaccineDao
ont déjà été créées mais elles ne portent pas les annotations Room.
Consignes
Dans le package
com.openclassRooms.Room.data.dao
, complétez le code des DAOsAnimalDao
etVaccineDao
avec les annotations Room :@Dao
@Query
@Upsert
@Delete
Livrables
Vous pouvez dupliquer le projet GitHub pour modifier le code source du projet et fournir un projet qui compile.
En résumé
L’annotation
@Dao
désigne une interface comme étant un DAO (Data Access Object).L’annotation
@Insert
indique qu’une méthode du DAO est une méthode d’insertion.L’annotation
@Query
permet d’écrire des requêtes SQL dont des requêtes de sélection.L’annotation
@Update
indique qu’une méthode du DAO est une méthode de mise à jour.L’annotation
@Upsert
indique qu’une méthode du DAO est une méthode d’insertion ou de mise à jour.L’annotation
@Delete
indique qu’une méthode du DAO est une méthode de suppression.
Vous avez défini la couche DAO permettant d’exposer l’ensemble des interactions possibles avec votre base de données grâce aux différentes annotations de Room. Nous pouvons maintenant finaliser la création de la base de données de l’application PETiSoin.