Fondamentalement, il y a deux choses que je ne comprends pas: les objets avec des objets et les objets avec des listes d'objets
Supposons que je reçoive une liste d'objets du serveur. Chacun d'eux ressemble à ceci:
@Entity
public class BigObject {
@PrimaryKey
private int id;
private User user;
private List<SmallObject> smallObjects;
}
avec ces deux objets comme champs:
@Entity
public class User {
@PrimaryKey
private int id;
private String name;
@TypeConverters(GenderConverter.class)
public MyEnums.Gender gender;
}
@Entity
public class SmallObject {
@PrimaryKey (autoGenerate = true)
private int id;
private String smallValue;
}
Ils sont plus compliqués que cela, donc je ne peux pas utiliser @TypeConverters comme le suggère Room:
error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
Comment stocker cette structure de données dans Room?
Je pense que la meilleure façon de répondre à cette question est un bref aperçu du stockage des structures ...
Listes
Room ne prend pas en charge le stockage de listes imbriquées dans un POJO. La méthode recommandée pour stocker des listes consiste à utiliser l'approche par clé étrangère. Stockez la liste d'objets dans une table séparée (dans ce cas, une table smallObjects) avec une clé étrangère vers leur objet parent associé (dans ce cas, "big_object_id"). Ça devrait ressembler a quelque chose comme ca...
@Entity
public class BigObject {
@PrimaryKey
private int id;
private User user;
@Ignore
private List<SmallObject> smallObjects;
}
@Entity(foreignKeys = {
@ForeignKey(
entity = BigObject.class,
parentColumns = "id",
childColumns = "big_object_fk"
)})
public class SmallObject {
@PrimaryKey (autoGenerate = true)
private int id;
private String smallValue;
@ColumnInfo(name = "big_object_fk")
private int bigObjectIdFk
}
Notez que nous avons ajouté le @Ignore
annotaiton à List<SmallObject>
car nous voulons ignorer le champ pendant la persistance de la pièce (car les listes ne sont pas prises en charge). Il existe maintenant de sorte que lorsque nous demandons notre liste de petits objets associés à la base de données, nous pouvons toujours les stocker dans le POJO.
À ma connaissance, cela signifie que vous effectuez deux requêtes.
BigObject b = db.BigObjectDao.findById(bOId);
List<SmallObject> s = db.smallObjectDao.findAllSOforBO(bOId);
b.setsmallObjects(s);
Il semble qu'il y ait une main courte pour cela sous la forme de @ Relation
Convertisseurs de type
Ce sont les cas où vous avez une structure de données complexe qui peut être flattée sans perdre d'informations et stockée dans une seule colonne. Un bon exemple de ceci est l'objet Date. Un objet Date est complexe et contient beaucoup de valeurs, donc le stocker dans la base de données est délicat. Nous utilisons un convertisseur de type pour extraire la représentation milli d'un objet date et la stocker. Nous convertissons ensuite les millis en objet de date à la sortie, gardant ainsi nos données intactes.
Intégré
Ceci est utilisé lorsque vous souhaitez prendre les champs de tous les POJO imbriqués dans votre POJO parent et les aplatir pour les stocker dans une table. un exemple :
- name
- age
- location
- x
- y
- DOB
..quand intégré cette structure serait stockée dans la base de données comme:
- name
- age
- location_x
- location_y
- DOB
Dans un sens, Embedded existe pour vous faire gagner du temps en créant des convertisseurs de type pour chaque objet imbriqué qui contient des champs de type principal tels que String, int, float, etc ...
List<Object>
à String, puis stockez-le.Vous pouvez stocker les objets dans la bibliothèque de pièces sous forme de chaîne. Pour cela, vous pouvez sérialiser l'objet et le stocker en tant que chaîne dans la base de données de la pièce.
Stocker dans la chambre
Objet -> Sérialiser -> Chaîne -> Stocker
Lire depuis la salle
Chaîne -> Désérialiser -> Objet -> Lire
De nombreuses options sont disponibles. Vous pouvez le faire manuellement ou utiliser une bibliothèque pour cela. Vous pouvez utiliser la bibliothèque de Google GSON . C'est assez simple à utiliser.
Code: objet -> chaîne
public String stringFromObject(List<YourClass> list){
Gson gson = new Gson();
String jsonString = gson.toJson(list);
return jsonString;
}
Code: String-> Object
public List<YourClass> getObjectFromString(String jsonString){
Type listType = new TypeToken<ArrayList<YourClass>>(){}.getType();
List<YourClass> list = new Gson().fromJson(jsonString, listType);
return list;
}