簡體   English   中英

通過Android Java中的主鍵獲取Realm對象的正確方法

[英]Proper way to get Realm object by its primary key in Android Java

我想知道是否有一種正確的方法來檢索一個對象,因為它在Realm for Android中具有主鍵。 我知道方法objectForPrimaryKey確實存在於Swift中,但在Realm for Android中似乎沒有這樣的對應物。 我真的認為做realm.where(EventInfo.class).equalTo("id", eventInfo.id).findFirst(); 看起來很浪費(至少它不是手腕友好的)。 我錯過了一些方法嗎? 我目前正在使用Realm 1.0.1

這就是為什么我有像這樣的Realm存儲庫(我寫的)

public class CalendarEventRepositoryImpl
        extends LongRealmRepositoryImpl<CalendarEvent>
        implements CalendarEventRepository {
    public CalendarEventRepositoryImpl() {
        super(CalendarEvent.class);
    }

    @Override
    public Long getId(CalendarEvent calendarEvent) {
        return calendarEvent.getId();
    }

    public void setId(CalendarEvent calendarEvent, Long id) {
        calendarEvent.setId(id);
    }

    public String getIdFieldName() {
        return CalendarEventFields.ID;
    }
}

我繼承了一個名為findOne(realm, id); 喜歡

CalendarEvent event = calendarEventRepository.findOne(realm, id);

但是,默認情況下,它是realm.where(CalendarEvent.class).equalTo("id", id).findFirst();

我最終為此創建了一個幫助類。 我將使用它,直到Realm團隊實現這些方法。 我已經將類命名為Find (您可以按照自己喜歡的方式對其進行重命名,因為命名事物和緩存失效是計算機科學中最難的事情 )。 我認為最好使用它而不是調用where().equalTo()將主鍵的名稱作為字符串值傳遞。 這樣您就可以使用正確的主鍵字段。 這是代碼:

import java.util.Hashtable;
import io.realm.Realm;
import io.realm.RealmModel;
import io.realm.RealmObjectSchema;

public final class Find {
    // shared cache for primary keys
    private static Hashtable<Class<? extends RealmModel>, String> primaryKeyMap = new Hashtable<>();

    private static String getPrimaryKeyName(Realm realm, Class<? extends RealmModel> clazz) {
        String primaryKey = primaryKeyMap.get(clazz);
        if (primaryKey != null)
            return primaryKey;
        RealmObjectSchema schema = realm.getSchema().get(clazz.getSimpleName());
        if (!schema.hasPrimaryKey())
            return null;
        primaryKey = schema.getPrimaryKey();
        primaryKeyMap.put(clazz, primaryKey);
        return primaryKey;
    }

    private static <E extends RealmModel, TKey> E findByKey(Realm realm, Class<E> clazz, TKey key) {
        String primaryKey = getPrimaryKeyName(realm, clazz);
        if (primaryKey == null)
            return null;
        if (key instanceof String)
            return realm.where(clazz).equalTo(primaryKey, (String)key).findFirst();
        else
            return realm.where(clazz).equalTo(primaryKey, (Long)key).findFirst();
    }

    public static <E extends RealmModel> E byKey(Realm realm, Class<E> clazz, String key) {
        return findByKey(realm, clazz, key);
    }

    public static <E extends RealmModel> E byKey(Realm realm, Class<E> clazz, Long key) {
        return findByKey(realm, clazz, key);
    }
}

用法很簡單:

// now you can write this
EventInfo eventInfo = Find.byKey(realm, EventInfo.class, eventInfoId);
// instead of this
EventInfo eventInfo = realm.where(EventInfo.class).equalTo("id", eventInfo.id).findFirst();

如果沒有給定對象的主鍵或者找不到該對象,它將返回null。 如果沒有主鍵,我考慮拋出異常,但認為它有點矯枉過正。

我真的很傷心Java泛型沒有C#泛型那么強大,因為我真的很想把這個方法調用如下:

Find.byKey<EventInfo>(realm, eventInfoId);

相信我,我試過了! 我到處搜索如何獲取方法的泛型類型返回值。 當它被證明是不可能的,因為Java擦除了泛型方法,我嘗試創建一個泛型類並使用:

(Class<T>)(ParameterizedType)getClass()
        .getGenericSuperclass()).getActualTypeArguments()[0];

所有可能的排列無濟於事! 所以我放棄了......

注意:我只實現了Find.byKey String和Long版本,因為Realm只接受String和Integral數據作為主鍵,Long也允許查詢Byte和Integer字段(我希望!)

我錯過了一些方法嗎?

不。 正如beeender所說,它目前尚未實施。 可以在此處跟蹤進度/討論。

輔助函數可能如下所示

public class Cat extends RealmObject {

    @PrimaryKey
    private int id;
    private String name;

    public Cat getByPrimaryKey(Realm realm, int id) {
        return realm.where(getClass()).equalTo("id", id).findFirst();
    }
}

這是一個特定於類的方法,因為每個類可以有不同的主鍵類型。 您必須將一個領域實例傳遞給您在調用類中管理的實例。

使用新的Realm,您可以使用數據庫的模式以這種方式訪問​​表的主鍵:

private String load(Class realmClass) {
  return mRealm.getSchema().get(realmClass.getSimpleName()).getPrimaryKey();
}

我在注釋方面不是很專業,我試圖通過反射在運行時讀取@PrimaryKey值,在字段上使用getAnnotation() ,但值總是為null ,可能是因為@Retention(RetentionPolicy.CLASS)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM