将领域与 Gson 一起使用
Using Realm with Gson
我有 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
,因为字符串的默认值为空。
所以,可能我错误地使用了该属性。 json(createOrUpdateObjectFromJson
等)守恒方法处理时如何考虑属性?
您可能需要一个混合解决方案才能完成这项工作。原因是 @SerializedName
是一个 GSON 注释,而不是 Realm 知道的注释。所以这意味着您有两个选择,正如您已经发现的那样:
1) 使用 GSON,这意味着最终结果是一个对象 null
作为 name
的默认值。
2) 使用 createOrUpdateObjectFromJson
这意味着 _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
Why writing all these custom serializers when you can make Gson and
Realm work together with just ONE LINE OF CODE?
IMO,为我们要序列化的每个模型设置独占策略并不是最好的方法。正如您已经意识到的,这种方法需要编写大量boiler-plate代码,这容易出错,最糟糕的是,杀死了 Gson 的意义(这让我们的生活不那么痛苦)。
而且由于我们 working-around 不兼容,你为什么不确保将未管理的 RealmObject 传递给你的 Gson序列化器?
有史以来最简单的解决方案 (IMO)
找到 here。在内存中获取托管 RealmObject 的副本并将其传递给 Gson
new Gson().toJson(realm.copyFromRealm(managedModel));
就是这样!无需再编写代码!
其他好的解决方案和解释是posted here.
我有 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
,因为字符串的默认值为空。
所以,可能我错误地使用了该属性。 json(createOrUpdateObjectFromJson
等)守恒方法处理时如何考虑属性?
您可能需要一个混合解决方案才能完成这项工作。原因是 @SerializedName
是一个 GSON 注释,而不是 Realm 知道的注释。所以这意味着您有两个选择,正如您已经发现的那样:
1) 使用 GSON,这意味着最终结果是一个对象 null
作为 name
的默认值。
2) 使用 createOrUpdateObjectFromJson
这意味着 _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
Why writing all these custom serializers when you can make Gson and Realm work together with just ONE LINE OF CODE?
IMO,为我们要序列化的每个模型设置独占策略并不是最好的方法。正如您已经意识到的,这种方法需要编写大量boiler-plate代码,这容易出错,最糟糕的是,杀死了 Gson 的意义(这让我们的生活不那么痛苦)。
而且由于我们 working-around 不兼容,你为什么不确保将未管理的 RealmObject 传递给你的 Gson序列化器?
有史以来最简单的解决方案 (IMO)
找到 here。在内存中获取托管 RealmObject 的副本并将其传递给 Gson
new Gson().toJson(realm.copyFromRealm(managedModel));
就是这样!无需再编写代码!
其他好的解决方案和解释是posted here.