次のようなAPI呼び出しからPOJOを解析しました
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;
}
冗長性と重複を最小限に抑えるために、私はこのようなスキーマを作成しようとしています
@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
}
ご覧のとおり、DAOメソッドを呼び出してデータベースにアクセスするとき、pojoオブジェクトを直接渡すことはできません(これについて誤解がない限り)。オブジェクトをデータベースエンティティモデルに一致するオブジェクトに変換する必要があると思います。
Android FrameworkはPOJOからデータベースモデルオブジェクトに変換する自然な方法を提供していますか?手動で変換する以外にこれを行う方法はありますか?
あなたがしなければならないすべては使用@Embedded
別のクラスを参照するPOJO(Model Class)の注釈。次に、型コンバータークラスを作成します。
@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;
}
別のクラスを参照する関連するPOJOに@ Embeddedアノテーションを使用できます。
あなたはこのようにすることができます:
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;
}
したがって、これを直接[〜#〜] pojo [〜#〜]をのエンティティとして使用できます[〜#〜]部屋[〜#〜]。
ご注意ください:
その関係をどのように処理するかはわかりませんが(Media objはArticleクラスのリストにあるため、そのために型コンバーターを使用する必要があります)
ここ からの参照
ドキュメントによると here 「エンティティまたは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
と単一のTypeConverters
を使用して、Dao
オブジェクトをRoom Database
内の列として実際に実装することもできました。
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;
}
}
それはあなたが試したことに対処します。次に、「オブジェクトをデータベースエンティティモデルに一致するオブジェクトに変換する必要があると思います」というステートメントに移ります。実際には、必ずしもそうではありません。 entry
の@Ignore
を含むデフォルトのコンストラクタが少なくとも1つある限り、エンティティのさまざまな作成インスタンスまたは実装にprimary key
アノテーションを使用できます。あなたの場合:
@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)
を使用して特定のDBにインポートできます。 。お役に立てれば!