首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数据库模型与网络模型

数据库模型与网络模型
EN

Stack Overflow用户
提问于 2014-05-01 22:02:32
回答 1查看 771关注 0票数 3

我用的是GreenDAO和截击。因此,我有以下问题:当我发出网络请求时,我需要使用GSON进行解析,因此我有一个模型来表示从服务器检索到的实体,还有其他模型来表示GreenDAO对象。是否有任何方法可以将每个模型只有一个类表示为GSON和ORM类?

产品类别:

代码语言:javascript
复制
@SerializedName("id")
private String id;

@SerializedName("pictures")
private List<Picture> pictures;

get & set

PersistentProduct类:

代码语言:javascript
复制
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返回类而不是接口,因此我认为不能这样做,我找到的唯一解决方案是创建一个"ProductUtils“,该"PersistentProduct”转换为“PersistentProduct”,反之亦然。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-05 09:27:15

最优雅的方法是为greendao实现一个小的扩展,以便您可以在模式创建期间指定序列化的名称。

例如:

de.greenrobot.daogenerator.Property.java

代码语言:javascript
复制
// 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};后)添加这一行:

代码语言:javascript
复制
<#if property.serializedName??>
import com.google.gson.annotations.SerializedName;
</#if>

和第55行之后(在:<#list entity.properties as property>之后)

代码语言:javascript
复制
<#if property.serializedName??>
@SerializedName("${property.serializedName}")
</#if>

之后,您应该能够使用您为volley生成的greendao实体,并具有以下限制

  1. 如果您通过网络获得了产品,则数据库中没有任何更改。你得打电话给insertOrReplace()
  2. 如果您从db获得一个产品并通过网络发送它,那么可能会序列化一些不想要的字段(即myDaodaoSession)。
  3. 如果您通过网络获得一个产品并调用insertOrReplace(),那么“网络”-Product将被持久化,并且已经存在的产品将被它替换--,但是如果没有为每个实体调用insertOrReplace(),则引用的实体不会被更新或持久化!
  4. 如果您通过网络获得一个产品,并为每个被引用的实体调用insertOrReplace(),则db引用的实体仍将被更新的产品引用,尽管更新的产品中没有列出这些实体。您必须调用resetPictures()getPictures()来获得正确的列表,该列表将包含存储在DB中的原始产品或网络更新的产品的所有toMany()-entities引用。

更新寻址2.

若要防止daoSessionmyDao被序列化,可以使用以下ExclusionStrategy

代码语言:javascript
复制
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中添加以下方法:

代码语言:javascript
复制
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();
}

这将导致更新原始实体并将其附加到会话和数据中。另外,网络产品引用的每一张图片都将被保存或更新。由原始实体引用的图片,而不是由网络实体引用的图片保持不变,并被合并到列表中。

这远非十全十美,但它表明了该去哪里做什么。接下来的步骤是在一个事务中完成在merge()中完成的所有操作,然后将不同的merge-methods集成到dao.ftl中。

注意:这个答案中给出的代码既不完整,也不经过测试,它是关于如何解决这个问题的一个提示。如上文所述,这一解决办法仍有一些限制,必须加以处理。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23417415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档