我正在使用GreenDAO和Volley。所以我有以下问题:当我发出网络请求时,我需要用GSON解析,所以我有一个模型来表示从服务器和其他模型中检索的实体来表示GreenDAO对象。有没有办法让每个模型只有1个类表示为GSON和ORM类?
类产品:
@SerializedName("id")
private String id;
@SerializedName("pictures")
private List<Picture> pictures;
get & set
类PersistentProduct:
private Long id;
private List<Picture> pictures;
/** To-many relationship, resolved on first access (and after reset). Changes to to-many relations are not persisted, make changes to the target entity. */
public List<PersistencePicture> getPictures() {
if (pictures == null) {
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
PersistencePictureDao targetDao = daoSession.getPersistencePictureDao();
List<PersistencePicture> picturesNew = targetDao._queryPersistenceProduct_Pictures(id);
synchronized (this) {
if(pictures == null) {
pictures = picturesNew;
}
}
}
return pictures;
}
首先我想创建一个接口,但是当你从DAO中检索数据时,DAO返回的是类而不是接口,所以我认为不能这样做,我找到的唯一解决方案就是做一个&# 34; ProductUtils&#34;转换自&#34; PersistentProduct&#34;到&#34;产品&#34;反之亦然。
答案 0 :(得分:1)
最优雅的方法是为greendao实现一个小扩展,以便您可以在模式创建期间指定序列化名称。
例如:
<强> de.greenrobot.daogenerator.Property.java 强>:
// in PropertyBuilder append these lines
public PropertyBuilder setSerializedName(String sname) {
// Check the sname on correctness (i.e. not empty, not containing illegal characters)
property.serializedName = sname;
return this;
}
// in Property append these lines
private String serializedName = null;
public boolean isSerialized() {
return serializedName != null;
}
在 entity.ftl 中,在第24行(package ${entity.javaPackage};
之后)添加此行:
<#if property.serializedName??>
import com.google.gson.annotations.SerializedName;
</#if>
在第55行(在<#list entity.properties as property>
之后)
<#if property.serializedName??>
@SerializedName("${property.serializedName}")
</#if>
之后你应该可以使用以下限制:使用生成的greendao-entity进行截击:
insertOrReplace()
。myDao
和daoSession
)insertOrReplace()
“网络” - 产品将被保留,现有产品将被其替换但引用的实体将不会如果没有为每个人调用insertOrReplace()
,请更新或保留!insertOrReplace()
,那么更新的产品仍然会引用db-Product引用的多个实体,尽管它们未在更新的产品中列出。您必须致电resetPictures()
和getPictures()
以获取正确的列表,该列表将包含所有toMany() - 由存储在数据库中的原始产品或来自网络的更新产品引用的实体。更新地址2。
要阻止序列化daoSession
和myDao
,您可以使用以下ExclusionStrategy
:
private static class TransientExclusionStrategy implements ExclusionStrategy {
public boolean shouldSkipClass(Class<?> clazz) {
return (clazz.getModifiers() & java.lang.reflect.Modifier.TRANSIENT) != 0;
}
public boolean shouldSkipField(FieldAttributes f) {
return f.hasModifier(java.lang.reflect.Modifier.TRANSIENT);
}
}
更新地址1.,3。和4。
作为快速解决方案,您可以在实体的KEEP-SECTIONS
中添加以下方法:
public void merge(DaoSession s) {
s.insertOrReplace(this);
// do this for all toMany-relations accordingly
for (Picture p : getPictures()) {
s.insertOrReplace(p);
newPics.add(p.getId());
}
resetPictures();
}
这将导致原始实体更新并附加到会话和dao。此外,网络产品引用的每个图片都将被保留或更新。原始实体引用的图片,但不是网络实体引用的图片保持不变,并合并到列表中。
这远非完美,但它显示了去哪里和做什么。接下来的步骤是在一个事务中执行merge()
中完成的所有操作,然后将不同的merge
- 方法集成到 dao.ftl 中。
注意强> 这个答案中给出的代码既不完整也不经过测试,而是暗示如何解决这个问题。如上所述,这个解决方案仍有一些限制,必须加以处理。