J'ai un POJO analysé à partir d'un appel API qui ressemble à ceci
public class Article {
public Long id;
@Expose
@SerializedName("section")
public String section;
@Expose
@SerializedName("title")
public String title;
@Expose
@SerializedName("topics")
public List<String> topics;
@Expose
@SerializedName("media")
public List<Media> media;
}
Pour minimiser la redondance et les doublons, je cherche à créer un schéma comme celui-ci
@Entity(foreignKeys = {
@ForeignKey(entity = Article.class, parentColumns = "id", childColumns = "articleId"),
@ForeignKey(entity = Topic.class, parentColumns = "id", childColumns = "topicId"),
@ForeignKey(entity = Media.class, parentColumns = "id", childColumns = "mediaId")
}
public class Articles {
@PrimaryKey
public Long articleId;
@ColumnInfo(name = "topic_id")
public Long topicId;
@ColumnInfo(name = "media_id")
public Long mediaId;
}
@Entity
public class Article {
// Left out
}
@Entity
public class Media {
// Left out
}
Comme vous pouvez le voir, lorsque j'appelle les méthodes DAO pour accéder à la base de données, je ne peux pas simplement passer directement l'objet pojo (sauf si je me trompe). Je crois que je dois transformer l'objet en un qui correspond au modèle d'entité de base de données.
Le framework Android fournit-il un moyen naturel de convertir de POJO en objet de modèle de base de données? Existe-t-il un moyen de le faire autre que de le convertir manuellement moi-même?
Tout ce que vous avez à faire est d'utiliser @Embedded
annotation pour votre POJO (classe de modèle) qui fera référence à une autre classe. puis créez une classe de convertisseur de type.
@Embedded(prefix = "media")
private Meida media;
@TypeConverters({TypeConvertorClass.class})
@Database(entities = {Article .class,Media.class}, version = 1, exportSchema = false)
public abstract class `DataBaseExample` extends RoomDatabase {
}
public class Converters {
@TypeConverter
public static ArrayList<String> fromString(String value) {
Type listType = new TypeToken<ArrayList<String>>() {}.getType();
return new Gson().fromJson(value, listType);
}
@TypeConverter
public static String fromArrayLisr(ArrayList<String> list) {
Gson gson = new Gson();
String json = gson.toJson(list);
return json;
}
}
public class TypeConvertorClass {
@TypeConverter
public static Media getMedia(String longId) {
return longId== null ? null : new Meida();
}
}
@Entity(tableName = "Article")
public class Article {
@ColumnInfo (name = "article_id")
public Long id;
@Expose
@SerializedName("section")
public String section;
@Expose
@SerializedName("title")
public String title;
@Expose
@SerializedName("topics")
public List<String> topics;
@Embedded(prefix = "media") // We need relation to Media table
@Expose
@SerializedName("media")
public List<Media> media;
}
public class Media {
@ColumnInfo (name = "media_id")
public Long id;
}
Vous pouvez utiliser @ Annotation intégrée pour votre POJO associé qui fait référence à une autre classe.
Vous pouvez faire comme ça:
Article.Java
@Entity(tableName = "Article")
public class Article {
@ColumnInfo (name = "article_id")
public Long id;
@Expose
@SerializedName("section")
public String section;
@Expose
@SerializedName("title")
public String title;
@Expose
@SerializedName("topics")
public List<String> topics;
@Embedded // We need relation to Media table
@Expose
@SerializedName("media")
public List<Media> media;
}
Media.Java
public class Media {
@ColumnInfo (name = "media_id")
public Long id;
}
Alors maintenant, vous pouvez directement utiliser ce [~ # ~] pojo [~ # ~] comme entité pour [~ # ~] chambre [~ # ~] .
Veuillez noter:
Bien que je ne sois pas sûr de la façon dont vous allez gérer cette relation (car, Media obj est dans la liste pour la classe Article, vous devrez utiliser le convertisseur de type pour cela)
Référence de ici
Selon la documentation ici "Il n'y a pas de limite au nombre de classes Entity ou Dao mais elles doivent être uniques dans la base de données." Je pense donc que vous pouvez simplement déclarer les différentes classes de votre classe de base de données qui étend RoomDatabase
.
Avez-vous essayé de simplement déclarer les différents POJO en tant qu'entités différentes et de les inclure tous dans la même classe de base de données?
Par exemple:
// Article, Topic and Media are classes annotated with @Entity.
@Database(version = 1, entities = {Article.class, Topic.class, Media.class})
abstract class MyDatabase extends RoomDatabase {
// ArticleDao is a class annotated with @Dao.
abstract public ArticleDao articleDao();
// TopicDao is a class annotated with @Dao.
abstract public TopicDao topicDao();
// MediaDao is a class annotated with @Dao.
abstract public MediaDao mediaDao();
}
Cela peut ne pas aider exactement à la redondance, mais ma pensée initiale serait également les convertisseurs de type. J'ai même réussi à implémenter un objet parcelable
en tant que colonne dans mon Room Database
En utilisant TypeConverters
et un seul Dao
.
Avez-vous essayé d'utiliser Gson
dans votre classe TypeConverter
? Je crois que cet article répond plus directement à votre question. C'est un guide pour stocker des objets dans une base de données de pièce. Encore une fois, l'astuce réside dans les convertisseurs de type et la déclaration de votre objet comme jeton de type pour Gson. Par exemple:
public class Converters {
@TypeConverter
public static List<Media> fromStringToList(String mediaListString) {
Type myType = new TypeToken<List<Media>>() {}.getType();
return new Gson().fromJson(mediaListString, myType);
}
@TypeConverter
public static String fromMediaListToString(List<Media> mediaItems) {
if (mediaItems== null || mediaItems.size() == 0) {
return (null);
}
Gson gson = new Gson();
Type type = new TypeToken<List<VideoParcelable>>() {
}.getType();
String json = gson.toJson(mediaItems, type);
return json;
}
}
Cela répond aux choses que vous avez essayées. Passons maintenant à votre déclaration "Je crois que je dois transformer l'objet en un objet qui correspond au modèle d'entité de base de données." En fait, pas nécessairement. Vous pouvez utiliser l'annotation @Ignore
Pour différentes instances de création ou implémentations de votre entité, tant qu'il existe au moins un constructeur par défaut qui inclut le primary key
Du entry
. Dans ton cas:
@Entity(foreignKeys = {
@ForeignKey(entity = Article.class, parentColumns = "id", childColumns =
"articleId"),
@ForeignKey(entity = Topic.class, parentColumns = "id", childColumns =
"topicId"),
@ForeignKey(entity = Media.class, parentColumns = "id", childColumns =
"mediaId")
}
public class ArticlesEntry {
@PrimaryKey
public Long articleId;
@ColumnInfo(name = "topic_id")
public Long topicId;
@ColumnInfo(name = "media_id")
public Long mediaId;
private Article articleObject;
private Media mediaObject;
//default constructor
public ArticlesEntry(int id) {
this.articleId = id;
}
//You can call this anytime you add to the database with media object input
@Ignore
public ArticlesEntry(int id, Media inMedia) {
this.articleId = id;
this.mediaObject= inMedia;
}
//You can create many of these and insert as needed, the left out variables of the
//are null, note that id has to be passed b/c your primary key isn't set to
//autogenerate
@Ignore
public ArticlesEntry(int id, Article inArticle) {
this.articleId = id;
this.articleObject= articleObject;
}
//Or both objects:
@Ignore
public ArticlesEntry(int id, Media inMedia, Article inArticle) {
this.articleId = id;
this.mediaObject = inMedia;
this.articleObject= articleObject;
}
//getters and setters here...
}
Si vous créez votre ArticlesEntry
comme ci-dessus, vous devrez créer et inclure les différents TypeConverters
, qui peuvent tous être dans la même classe et importés dans la base de données spécifique avec @TypeConverters(MyConverters.class)
. J'espère que cela t'aides!