领域:没有索引的 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();
}
}
问题:
- 这样的设计好吗(有静态函数以便于使用)?我喜欢如何将新条目插入到缓存中,如
ExchangePairPriceCache.add("NASDAQ", "AAPL", "USD", 100.5);
并在需要时使用 ExchangePairPriceCache.deleteAll()
删除所有条目。
- 如何简化
add()
函数?现在我检查条目是否已经存在,然后更新价格,如果不存在,我创建一个新对象并将其插入到 Realm 中。我无法使用 updateOrInsert
因为我没有对象的唯一索引。
也许是我太自问了,这一切都很好。但我非常感谢每天使用它的专家的一些意见。
您应该将 "Repository design pattern" 与 DAO 对象(数据访问对象)一起使用,以在领域中执行所有读/写事务。
模型 class 应该是仅包含实体的对象的盲目副本。
由于您没有任何唯一标识符,您可以尝试以下
- 在共享首选项文件中缓存 Exchange 对(如果它们是否较早添加)
- 为了更快 read/writes : 使用您已有的键值对组合创建一个临时唯一标识符
例如:(exchangeName + baseCurrency + quoteCurrency) - 转换为适当的格式以创建具有所有这些值的一些唯一键。
我有一个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();
}
}
问题:
- 这样的设计好吗(有静态函数以便于使用)?我喜欢如何将新条目插入到缓存中,如
ExchangePairPriceCache.add("NASDAQ", "AAPL", "USD", 100.5);
并在需要时使用ExchangePairPriceCache.deleteAll()
删除所有条目。 - 如何简化
add()
函数?现在我检查条目是否已经存在,然后更新价格,如果不存在,我创建一个新对象并将其插入到 Realm 中。我无法使用updateOrInsert
因为我没有对象的唯一索引。
也许是我太自问了,这一切都很好。但我非常感谢每天使用它的专家的一些意见。
您应该将 "Repository design pattern" 与 DAO 对象(数据访问对象)一起使用,以在领域中执行所有读/写事务。
模型 class 应该是仅包含实体的对象的盲目副本。
由于您没有任何唯一标识符,您可以尝试以下
- 在共享首选项文件中缓存 Exchange 对(如果它们是否较早添加)
- 为了更快 read/writes : 使用您已有的键值对组合创建一个临时唯一标识符 例如:(exchangeName + baseCurrency + quoteCurrency) - 转换为适当的格式以创建具有所有这些值的一些唯一键。