6

我有json字段_id

 String json = "{ _id : 1, name : 'Alex', role: 'admin' }"

在我的领域模型中,我使用@SerializedName属性:

public class User extends RealmObject {

    @SerializedName("_id")  
    @PrimaryKey
    private int id;
    private String name;
    private String comment;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

}  

如果尝试保存 json:

realm.createOrUpdateObjectFromJson(User.class, json)

字段_id无法解析,并且在数据库中创建了 id = 0 的记录

@SerializedName在使用属性的文档中

  Gson gson = new GsonBuilder()
            .setExclusionStrategies(new ExclusionStrategy() {
                @Override
                public boolean shouldSkipField(FieldAttributes f) {
                    return f.getDeclaringClass().equals(RealmObject.class);
                }

                @Override
                public boolean shouldSkipClass(Class<?> clazz) {
                    return false;
                }
            }).create();


User user = gson.fromJson(json, User.class);
realm.beginTransaction();
realm.copyToRealmOrUpdate(user);

在这种情况下json = "{ _id : 1, role: 'user' }",只需从数据库中删除用户name,因为 String 的默认值为 null。

所以,可能我错误地使用了该属性。createOrUpdateObjectFromJson处理json(等)的守恒方法时如何考虑属性?

4

2 回答 2

15

当您可以使GsonRealm只用一行代码一起工作时,为什么还要编写所有这些自定义序列化程序?

IMO,为我们想要序列化的每个模型设置专有策略并不是最好的方法。正如您已经意识到的那样,这种方法需要编写大量容易出错的样板代码,最糟糕的是,会扼杀Gson意义(这使我们的生活不那么痛苦)。

既然我们正在解决不兼容问题,为什么不确保将未管理的 RealmObject传递Gson序列化程序?

有史以来最简单的解决方案(IMO)

在这里找到。在内存中获取托管RealmObject的副本并将其传递给Gson

new Gson().toJson(realm.copyFromRealm(managedModel));

就是这样!不用再写代码了!

其他好的解决方案和解释发布在这里。

于 2017-02-04T19:21:06.497 回答
4

您可能需要一个混合解决方案才能完成这项工作。原因是这@SerializedName是一个 GSON 注释,而不是 Realm 知道的注释。因此,这意味着您已经发现了两种选择:

1) 使用 GSON,这意味着最终结果是一个对象,null默认为name.

2) 使用createOrUpdateObjectFromJsonwhich 意味着_id将被忽略,因为 Realm 的 JSON 解析器需要 1:1 映射。

由于这两种解决方案都不能正常工作,您可以通过以下方式修改它们:

1)使用 GSON,copyToRealmOrUpdate您可以手动搜索对象并更新角色,而不是这样做:

realm.beginTransaction();
realm.where(User.class).equalTo("id", user.getId()).findFirst().setRole(user.getRole());
realm.commitTransaction();

2) 仅使用纯 JSON,您可以修改以匹配预期格式:

JSONObject obj = new JSONObject(json);
obj.put("id", obj.getString("_id"));
obj.remove("_id");

Realm 在跟踪自定义映射请求时存在问题,但它的优先级较低,因为 GSON、Jacokson 等框架通常会更好地覆盖该功能:https ://github.com/realm/realm-java/issues /1470

于 2016-02-10T10:23:03.160 回答