2015-09-08 13 views
8

Giúp mọi người! Kịch bản của tôi là tôi có một màn hình với một nguồn cấp dữ liệu và mỗi mục nguồn cấp dữ liệu với chi tiết của nó được lưu trữ trong một lĩnh vực. Mỗi mục trong số này có các thuộc tính offset và feedPostedAt được định nghĩa. Sự cố xảy ra khi người dùng nhấp vào chi tiết của mục và mục được tải xuống để cung cấp dữ liệu hiện tại. Tuy nhiên, chi tiết tải xuống không chứa thuộc tính offset và feedPostedAt do đó khi tôi cập nhật trong lĩnh vực (realm.copyOrUpdate()) mục này mục cũ với các thuộc tính offset và feedPostedAt được xác định sẽ bị ghi đè.Cách cập nhật chỉ các giá trị NOT NULL khi ghi dữ liệu vào Realm

Có cách nào mà lĩnh vực cập nhật chỉ các giá trị được xác định và để các thuộc tính có giá trị NULL bị ảnh hưởng không?

Hiện tại tôi đang xử lý sự cố này theo cách tôi đặt lại thuộc tính offset và feedPostedAt theo cách thủ công nhưng không đẹp và cũng không hiệu quả.

+2

Tôi không nghĩ rằng có thể, trừ khi bạn tự mình lập bản đồ (https://github.com/realm/realm-java/issues/1344) – EpicPandaForce

+0

Sử dụng thư viện Gson để phân tích cú pháp dữ liệu. Nó sẽ phân tích cú pháp và cập nhật dữ liệu mới mà phản hồi api của bạn chứa. Các trường còn lại sẽ vẫn giữ nguyên. –

+0

@NooruddinLakhani Tôi đã phân tích cú pháp phản hồi api bằng cách sử dụng thư viện Gson sau đó tôi tự ánh xạ phản hồi tới RealmObject vừa tạo và sau đó tôi sử dụng phương thức copyOrUpdate. Tôi sẽ thử createOrUpdateObjectFromJson(). –

Trả lời

1

Có thể hơi trễ nhưng đây là những gì tôi sử dụng. Phương pháp này cập nhật đối tượng base với các thuộc tính không có giá trị mặc định của đối tượng update. Sau đó, phương pháp Realm#insertOrUpdate được sử dụng để cập nhật cơ sở dữ liệu realm.

/** 
* 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(); 
     } 
    } 
} 
  • Nó sử dụng phản ánh để truy cập tất cả tài sản.
  • Cả hai đối tượng phải được tách ra khỏi lĩnh vực.
  • Mô hình đối tượng phải có @PrimaryKey thuộc tính được chú thích theo thứ tự Realm#insertOrUpdate để thực hiện công việc của mình. Nếu không, phương pháp yêu cầu một chút điều chỉnh.
Các vấn đề liên quan