【问题标题】:How to update only NOT NULL values when writing data to Realm将数据写入Realm时如何仅更新NOT NULL值
【发布时间】:2015-09-08 10:54:25
【问题描述】:

大家好! 我的场景是我有一个带有提要的屏幕,并且每个提要项及其详细信息都存储在一个领域中。这些项目中的每一个都定义了 offset 和 feedPostedAt 属性。当用户单击一个项目并下载项目的详细信息以提供当前数据时,就会出现问题。但是,下载的详细信息不包含属性 offset 和 feedPostedAt,因此当我在领域 (realm.copyOrUpdate()) 中更新此项目时,具有定义的 offset 和 feedPostedAt 属性的旧项目将被覆盖。

有没有办法让领域只更新已定义的值,而使具有 NULL 值的属性保持不变?

现在我正在以手动重置偏移量和 feedPostedAt 属性的方式处理这个问题,但这既不好也不有效。

【问题讨论】:

  • 我认为这是不可能的,除非您自己手动进行映射 (github.com/realm/realm-java/issues/1344)
  • 使用 Gson 库解析数据。它将解析和更新您的 api 响应包含的新数据。其余字段将保持原样。
  • @NooruddinLakhani 我已经在使用 Gson 库解析 api 响应,然后我手动将响应映射到新创建的 RealmObject,然后我使用 copyOrUpdate 方法。我会尝试 createOrUpdateObjectFromJson()。

标签: android realm


【解决方案1】:

可能有点晚了,但这是我使用的。该方法使用update 对象的非默认值属性更新base 对象。然后Realm#insertOrUpdate方法用于更新领域数据库。

    /**
 * Both classes must be detached from realm.
 * Primitives compared with their defaults.
 * check <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.5"/>default values of primitives</>
 */
public static <T> void updateObject(T base, T update) {
    Class<?> aClass = base.getClass();
    for (Field field : aClass.getDeclaredFields()) {
        try {
            field.setAccessible(true);
            Class<?> fieldType = field.getType();
            if (fieldType.isPrimitive()) {
                if (fieldType.equals(boolean.class)) {
                    if (field.getBoolean(update)) {
                        field.setBoolean(base, true);
                    }
                } else if (fieldType.equals(int.class)) {
                    if (field.getInt(update) != 0) {
                        field.setInt(base, field.getInt(update));
                    }
                } else if (fieldType.equals(long.class)) {
                    if (field.getLong(update) != 0L) {
                        field.setLong(base, field.getLong(update));
                    }
                } else if (fieldType.equals(short.class)) {
                    if (field.getShort(update) != (short) 0) {
                        field.setShort(base, field.getShort(update));
                    }
                } else if (fieldType.equals(byte.class)) {
                    if (field.getByte(update) != (byte) 0) {
                        field.setByte(base, field.getByte(update));
                    }
                } else if (fieldType.equals(float.class)) {
                    if (field.getFloat(update) != 0.0f) {
                        field.setFloat(base, field.getFloat(update));
                    }
                } else if (fieldType.equals(double.class)) {
                    if (field.getDouble(update) != 0.0d) {
                        field.setDouble(base, field.getDouble(update));
                    }
                } else if (fieldType.equals(char.class)) {
                    if (field.getChar(update) != '\u0000') {
                        field.setChar(base, field.getChar(update));
                    }
                }
            } else {
                Object newValue = field.get(update);
                if (newValue != null) {
                    field.set(base, newValue);
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}
  • 它使用反射来访问所有属性。
  • 这两个对象都必须从领域中分离出来。
  • 对象模型应该具有@PrimaryKey 注释属性,以便Realm#insertOrUpdate 完成其工作。否则方法需要一些调整。

【讨论】:

    猜你喜欢
    • 2020-01-31
    • 1970-01-01
    • 1970-01-01
    • 2019-01-21
    • 2015-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-27
    相关资源
    最近更新 更多