Согласно документации здесь «Количество классов Entity или Dao не ограничено, но они должны быть уникальными в базе данных».Поэтому я думаю, что вы можете просто объявить различные классы в вашем классе базы данных, который расширяет RoomDatabase
.
Вы пытались просто объявить разные POJO как разные сущности и включить их всех в один и тот же класс базы данных?
Например:
// 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();
}
Это может не совсем помочьс избыточностью, но моя первоначальная мысль была бы и о преобразователях типов.На самом деле я даже успешно реализовал объект parcelable
в виде столбца в моем Room Database
, используя TypeConverters
и один Dao
.
Вы пытались использовать Gson
в своем классе TypeConverter
?Я считаю, эта статья решает ваш вопрос более прямо.Это руководство по хранению объектов в базе данных комнаты.Опять же, хитрость заключается в преобразователях типов и объявлении вашего объекта в качестве токена типа для Gson.Например:
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;
}
}
Это относится к тому, что вы пробовали.Теперь перейдем к вашему утверждению «Я считаю, что мне нужно преобразовать объект в объект, соответствующий модели сущности базы данных».На самом деле, не обязательно.Вы можете использовать аннотацию @Ignore
для различных экземпляров создания или реализаций вашей сущности, если есть хотя бы один конструктор по умолчанию, который включает primary key
из entry
.В вашем случае:
@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...
}
Если вы создадите ArticlesEntry
, как описано выше, вам нужно будет создать и включить другой TypeConverters
, который может быть в одном классе и импортирован в конкретный класс.БД с @TypeConverters(MyConverters.class)
.Надеюсь, это поможет!