在房间中访问和存储多个 POJO 类



我有多个POJO类作为主POJO类的类型,我正在使用它们来解析使用Retrofit的json数据。所以我为第一级 Pojo 提供了类型转换器,但我在读取存储的数据时遇到问题,因为它的格式不正确。

这是我的POJO课程

@Entity(tableName = "entry")
public class Entry implements Parcelable {
@NonNull
@PrimaryKey
@SerializedName("id")
private FeedID feedId;
@SerializedName("title")
private Title EntryTitle;
@SerializedName("im:image")
private List<Image> image;
@SerializedName("summary")
private Summary summary;
public Entry(){}
public FeedID getFeedId() {
return feedId;
}
public void setFeedId(FeedID feedId) {
this.feedId = feedId;
}
public Title getEntryTitle() {
return EntryTitle;
}
public void setEntryTitle(Title entryTitle) {
this.EntryTitle = entryTitle;
}
public List<Image> getImage() {
return image;
}
public void setImage(List<Image> image) {
this.image = image;
}
public Summary getSummary() {
return summary;
}
public void setSummary(Summary summary) {
this.summary = summary;
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<Entry> CREATOR = new Parcelable.Creator<Entry>() {
@Override
public Entry createFromParcel(Parcel in) {
return new Entry(in);
}
@Override
public Entry[] newArray(int size) {
return new Entry[size];
}
};
protected Entry(Parcel in) {
feedId = (FeedID) in.readValue(FeedID.class.getClassLoader());
EntryTitle = (Title) in.readValue(Title.class.getClassLoader());
if (in.readByte() == 0x01) {
image = new ArrayList<Image>();
in.readList(image, Image.class.getClassLoader());
} else {
image = null;
}
summary = (Summary) in.readValue(Summary.class.getClassLoader());
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(feedId);
dest.writeValue(EntryTitle);
if (image == null) {
dest.writeByte((byte) (0x00));
} else {
dest.writeByte((byte) (0x01));
dest.writeList(image);
}
dest.writeValue(summary);
}
public class Title implements Parcelable {
private String label;
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
@SuppressWarnings("unused")
public final Parcelable.Creator<Title> CREATOR = new Parcelable.Creator<Title>() {
@Override
public Title createFromParcel(Parcel in) {
return new Title(in);
}
@Override
public Title[] newArray(int size) {
return new Title[size];
}
};
protected Title(Parcel in) {
label = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(label);
}
}
public class Image implements Parcelable {
private String label;
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
@SuppressWarnings("unused")
public final Parcelable.Creator<Image> CREATOR = new Parcelable.Creator<Image>() {
@Override
public Image createFromParcel(Parcel in) {
return new Image(in);
}
@Override
public Image[] newArray(int size) {
return new Image[size];
}
};
protected Image(Parcel in) {
label = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(label);
}
}
public class Summary implements Parcelable {
private String label;
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
@SuppressWarnings("unused")
public final Parcelable.Creator<Summary> CREATOR = new Parcelable.Creator<Summary>() {
@Override
public Summary createFromParcel(Parcel in) {
return new Summary(in);
}
@Override
public Summary[] newArray(int size) {
return new Summary[size];
}
};
protected Summary(Parcel in) {
label = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(label);
}
}
public class FeedID implements Parcelable {
private Attributes attributes;
public Attributes getAttributes() {
return attributes;
}
public void setAttributes(Attributes attributes) {
this.attributes = attributes;
}

@SuppressWarnings("unused")
public final Parcelable.Creator<FeedID> CREATOR = new Parcelable.Creator<FeedID>() {
@Override
public FeedID createFromParcel(Parcel in) {
return new FeedID(in);
}
@Override
public FeedID[] newArray(int size) {
return new FeedID[size];
}
};
protected FeedID(Parcel in) {
attributes = (Attributes) in.readValue(Attributes.class.getClassLoader());
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(attributes);
}
}
public class Attributes implements Parcelable {
@SerializedName("im:id")
private String id;
public String getIm() {
return id;
}
public void setIm(String im) {
this.id = im;
}
@SuppressWarnings("unused")
public final Parcelable.Creator<Attributes> CREATOR = new Parcelable.Creator<Attributes>() {
@Override
public Attributes createFromParcel(Parcel in) {
return new Attributes(in);
}
@Override
public Attributes[] newArray(int size) {
return new Attributes[size];
}
};
protected Attributes(Parcel in) {
id = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(id);
}
}
}

这是我的类型转换器类

public class RoomTypeConverters {
@TypeConverter
public static String toString(Entry.Title value) {
Gson gson = new Gson();
String json = gson.toJson(value);
return json;
}
@TypeConverter
public static Entry.Title toTitle(String value) {
Type listType = new TypeToken<Entry.Title>() {
}.getType();
return new Gson().fromJson(value, listType);
}
@TypeConverter
public static String toString(Entry.FeedID value) {
Gson gson = new Gson();
String json = gson.toJson(value);
return json;
}
@TypeConverter
public static Entry.FeedID toFeedID(String value) {
Type listType = new TypeToken<Entry.FeedID>() {
}.getType();
return new Gson().fromJson(value, listType);
}
@TypeConverter
public static String toString(Entry.Summary value) {
Gson gson = new Gson();
String json = gson.toJson(value);
return json;
}
@TypeConverter
public static Entry.Summary toSummary(String value) {
Type listType = new TypeToken<Entry.Summary>() {
}.getType();
return new Gson().fromJson(value, listType);
}
@TypeConverter
public static String toString(List<Entry.Image> value) {
Gson gson = new Gson();
String json = gson.toJson(value);
return json;
}
@TypeConverter
public static List<Entry.Image> toImage(String value) {
Type listType = new TypeToken<Entry.Summary>() {
}.getType();
return new Gson().fromJson(value, listType);
}
}

我是否必须只为一个字段创建多个这样的 POJO?我们还有其他选择吗?

是的,要保存 POJO,您必须为其定义一个类(内部或普通类(。

但我从您的数据架构中了解到的是,您有一个可能复杂的数据存储服务器端,并且您希望在应用程序中使用该数据的子集。例如,您的 POJO 可以简化,因此您可以创建一个名为EntryRecord的类,并为它定义一个简单的 setter 和 getter,如下所示:

@Entity(tableName = "entry")
public class EntryRecord {
@NonNull
@PrimaryKey
@SerializedName("id")
private String feedId;
@SerializedName("title")
private StringEntryTitle;
@SerializedName("im:image")
private String[] image;
@SerializedName("summary")
private String summary;
public EntryRecord(Entry entry){
//Resolve primitive values from Entry class attributes..
}
public Entry getEntry(){
Entry entry = new Entry();
//Resolve entry values from primitive ones...
return entry ;
}
}

,现在您所要做的就是使用此类来保存和恢复您的数据,您可以在保存之前将DAO抽象化以转换您的 POJO,反之亦然。

PS:如果你对具有这么多单变量类的复杂模式没有任何用处,我真的建议您定义自定义GSONserializer/deserializer从一开始就将复杂的 POJO 转换为简化的 POJO;从代码库中完全删除如此复杂的模式。

因此,经过一番研究,我发现了一个注释,如果您有多个内部类,房间将处理它,并且您不必为它创建任何TypeConverters。

@Embedded可用作实体或 Pojo 字段的注释,以指示嵌套字段(即注释字段类的字段(可以直接在 SQL 查询中引用。

例如,如果您有 2 个类:

public class Coordinates {
double latitude;
double longitude;
}
public class Address {
String street;
@Embedded
Coordinates coordinates;
}

在将 SQLite 行映射到地址时,Room 将考虑纬度和经度,就好像它们是 Address 类的字段一样。

来源 : 文档

最新更新