J'utilise Room comme base de données pour l'application. J'ai un scénario où une Object
d'un certain type doit être stockée dans des tables séparées. Par exemple, prenons la Object
appelée Book.Java
Maintenant, je veux avoir deux tables SQL:
ignore toutes les conventions de nommage pour SQL DB s'il vous plaît - ceci est juste un exemple
Problème
Normalement, on utilisera simplement @Entity(tableName = "Books_Read")
dans la classe Book.Java
et on aura une classe DAO
qui utilisera ce nom de table.
La chose est; Comment pourrais-je alors utiliser la même classe Book.Java
pour la stocker dans la table Books_To_Read
? Depuis que j'ai déjà défini @Entity(tableName = "Books_Read")
dans la classe Book.Java
et que je ne vois pas où définir la table Books_To_Read
pour la classe Book.Java
La seule solution que j'ai pu trouver, ce qui me semble un peu hackery et unnessasery, était de créer une nouvelle classe - appelons-la BookToRead.Java
qui étend Book.Java
et définisse @Entity(tableName = "Books_To_Read")
dans la classe.
Question
Y a-t-il une meilleure façon de faire ceci ou est-ce la manière attendue de le gérer?
Est-ce la manière attendue de le gérer?
Non . C'est une mauvaise approche. Vous devriez éliminer la duplication de données pour plusieurs raisons.
Cela coûtera de l'espace de stockage. Au fur et à mesure que la taille de la base de données augmente, cela va devenir de plus en plus grave.
Cela compliquera le système. Si vous mettez à jour un seul champ , Vous devrez peut-être effectuer la même action à différents endroits . Si vous manquez l'un d'eux, les données complètes deviendront Incohérentes. Il est possible d'effectuer des opérations telles que Une seule transaction. Mais il est toujours préférable de garder la structure de la base de données Pure.
Méthode 1: Introduire de nouveaux tableaux
Vous pouvez stocker les détails des livres dans une seule table, par exemple, "Books"
. "Books_To_Read"
ou toute autre table ne doit contenir que la référence à la table "Books"
(en utilisant l'identifiant/la clé primaire dans la table "Books"
). Vous pouvez ensuite utiliser le mot clé JOIN
pour obtenir la totalité de l'enregistrement en une seule requête.
Cette méthode est recommandée si chaque type (livres lus et non lus dans ce cas) a son propre ensemble de champs (Comme le read_date, read_time pour les livres lus et wish_to_read pour les livres non lus).
Méthode 2: Introduire un nouveau champ
Vous pouvez simplement ajouter un nouveau type qui spécifie le type. Dans ce cas, il n'y a que deux types (lu et non lu), un champ booléen (quelque chose comme is_read
) conviendra.
Ce serait la méthode la plus simple. Mais cela ne fonctionnera que si vous voulez simplement indiquer à quel type appartient la ligne. Si vous avez besoin de stocker des données de type spécifique et que vous introduisez des champs supplémentaires à cette fin, n'oubliez pas que ces champs existent également pour d'autres types.
Voici comment j'ai finalement résolu ce problème:
J'ai ajouté un identifiant à la classe Book.Java
qui indique s'il a été lu ou non. Soutenue par une EnumType
qui était soit book_read
ou book_unread
, puis dans ma DAO
pour "BooksDataTable"
, je n'utilisais alors qu'un SQL query
à select
la ID
que je veux. Donc, en changeant la requête, je peux obtenir tous les books_read
ou books_to_read
ou all_books
. De cette façon, il n'y a pas de duplication de données et tout est dans une table, sans avoir à utiliser les relations JOIN
ou OneToMany
.
@OneToMany(mappedBy="book_id")
private Set<Book> book
Je pense que c'est le meilleur moyen de connecter deux tables. Essayez-le et laissez-moi savoir votre retour d'information. Je vais donner une autre solution
J'étais en train d'écrire un exemple d'application quand Ahamad a donné sa réponse.
Room fournit une couche d'abstraction sur SQLite pour permettre une utilisation fluide accès à la base de données tout en exploitant toute la puissance de SQLite.
l'idée principale est la même que celle de stocker les données du livre dans une table et d'utiliser l'identifiant du livre dans d'autres tables regardez mon exemple projet
résultat de logcat
02-19 16:39:26.741 10520-10520/com.example.jingged.roomtest E/MainActivity: Book{id = 1 name = Book 0, author Author 0}
02-19 16:39:26.741 10520-10520/com.example.jingged.roomtest E/MainActivity: Book{id = 2 name = Book 1, author Author 1}
02-19 16:39:26.741 10520-10520/com.example.jingged.roomtest E/MainActivity: Book{id = 3 name = Book 2, author Author 2}
02-19 16:39:26.741 10520-10520/com.example.jingged.roomtest E/MainActivity: Book{id = 4 name = Book 3, author Author 3}
02-19 16:39:26.767 10520-10520/com.example.jingged.roomtest E/MainActivity: BookToRead Book{id = 3 name = Book 2, author Author 2}
02-19 16:39:26.767 10520-10520/com.example.jingged.roomtest E/MainActivity: BookToRead Book{id = 4 name = Book 3, author Author 3}
02-19 16:39:26.768 10520-10520/com.example.jingged.roomtest E/MainActivity: BooksRead Book{id = 1 name = Book 0, author Author 0}
02-19 16:39:26.768 10520-10520/com.example.jingged.roomtest E/MainActivity: BooksRead Book{id = 2 name = Book 1, author Author 1}