领域:没有索引的 updateOrInsert

Realm: updateOrInsert without index

我有一个RealmObject,它仅用作临时数据缓存(会有很多条目)。我还写了一个静态方法 add() 所以我可以很容易地添加一个新条目,但它似乎太复杂了。这是整个class:

public class ExchangePairPriceCache extends RealmObject {
    @Index
    private String exchangeName;
    @Index
    private String baseCurrency;
    @Index
    private String quoteCurrency;
    private float price;
    private long lastPriceUpdate;

    public ExchangePairPriceCache() {
        exchangeName = "";
        baseCurrency = "";
        quoteCurrency = "";
        price = 0;
        lastPriceUpdate = 0;
    }

    public ExchangePairPriceCache(String exchangeName, String baseCurrency, String quoteCurrency) {
        this.exchangeName = exchangeName;
        this.baseCurrency = baseCurrency;
        this.quoteCurrency = quoteCurrency;
        price = 0;
        lastPriceUpdate = 0;
    }

    public void setPrice(float price) {
        // this needs to be called inside a Realm transaction if it's a managed object
        this.price = price;
        lastPriceUpdate = System.currentTimeMillis();
    }

    public float getPrice() {
        return price;
    }

    /* static functions */
    public static void add(String exchangeName, String baseCurrency, String quoteCurrency, float price) {
        Realm realm = Realm.getDefaultInstance();
        realm.executeTransaction(r -> {
            ExchangePairPriceCache priceCache = r.where(ExchangePairPriceCache.class)
                    .equalTo("exchangeName", exchangeName)
                    .equalTo("baseCurrency", baseCurrency)
                    .equalTo("quoteCurrency", quoteCurrency).findFirst();
            if(priceCache != null) {
                priceCache.setPrice(price);
            } else {
                priceCache = new ExchangePairPriceCache(exchangeName, baseCurrency, quoteCurrency);
                priceCache.setPrice(price);
                ExchangePairPriceCache finalPriceCache = priceCache;
                r.insert(finalPriceCache);
            }
        });
        realm.close();
    }

    public static ExchangePairPriceCache get(String exchangeName, String baseCurrency, String quoteCurrency) {
        Realm realm = Realm.getDefaultInstance();
        ExchangePairPriceCache priceCache = realm.where(ExchangePairPriceCache.class)
                .equalTo("exchangeName", exchangeName)
                .equalTo("baseCurrency", baseCurrency)
                .equalTo("quoteCurrency", quoteCurrency)
                .greaterThan("lastPriceUpdate", System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(10)).findFirst();
        if(priceCache != null)
            priceCache = realm.copyFromRealm(priceCache);
        realm.close();

        return priceCache;
    }

    public static void deleteAll() {
        Realm realm = Realm.getDefaultInstance();
        realm.executeTransaction(r -> r.delete(ExchangePairPriceCache.class));
        realm.close();
    }
}

问题:

  1. 这样的设计好吗(有静态函数以便于使用)?我喜欢如何将新条目插入到缓存中,如 ExchangePairPriceCache.add("NASDAQ", "AAPL", "USD", 100.5); 并在需要时使用 ExchangePairPriceCache.deleteAll() 删除所有条目。
  2. 如何简化 add() 函数?现在我检查条目是否已经存在,然后更新价格,如果不存在,我创建一个新对象并将其插入到 Realm 中。我无法使用 updateOrInsert 因为我没有对象的唯一索引。

也许是我太自问了,这一切都很好。但我非常感谢每天使用它的专家的一些意见。

您应该将 "Repository design pattern" 与 DAO 对象(数据访问对象)一起使用,以在领域中执行所有读/写事务。

模型 class 应该是仅包含实体的对象的盲目副本。

由于您没有任何唯一标识符,您可以尝试以下

  1. 在共享首选项文件中缓存 Exchange 对(如果它们是否较早添加)
  2. 为了更快 read/writes : 使用您已有的键值对组合创建一个临时唯一标识符 例如:(exchangeName + baseCurrency + quoteCurrency) - 转换为适当的格式以创建具有所有这些值的一些唯一键。