我开始在我正在编写的Android应用中使用Realm.io。在我的一个数据对象中,我需要存储货币值。以前我在内部将值存储为BigDecimal值,然后在进出数据库时将值转换为double值。
我一直被告知,由于处理它们的方式,将货币值存储在双倍中是一个坏主意。不幸的是,Realm.io不支持存储和检索BigDecimal对象。
编写我自己的扩展RealmObject的货币类并将其作为数据对象的成员变量保留的最佳解决方案是什么?
答案 0 :(得分:6)
来自Realm的Emanuele。
你是对的,使用花车或双打作为货币是糟糕的想法。
我们暂时不支持BigDecimal,在我们开始之前,我们必须看看它与所有其他语言绑定的关系,因为我们希望realm文件在所有支持的平台上兼容。
克里斯蒂安的想法很好,但我看到和String的转换有点慢。如果您不需要BigDecimal的任意精度属性,则可以使用long
并乘以/除以所需精度所需的因子。这也可以在Realm文件的大小方面节省大量空间,因为整数值是有点打包的。
答案 1 :(得分:5)
这可能会有效,但如果对当前的BigDecimal对象进行计算,则可能不是最理想的。
您还可以使用@Ignore注释为自定义对象提供包装方法,如下所示:
public class Money extends RealmObject {
private String dbValue;
@Ignore private BigDecimal value;
public String getDbValue() {
return dbValue;
}
public void setDbValue(String dbValue) {
this.dbValue = dbValue;
}
public BigDecimal getValue() {
return new BigDecimal(getDbValue());
}
public void setValue(BigDecimal value) {
setDbValue(value.toString());
}
}
它不完美,因为你需要公开* dbValue()方法,但它应该可以工作。
我还建议前往https://github.com/realm/realm-java/issues并为此发出一个功能请求,因为BigDecimal可能是许多人使用的java类之一,它可以保证本机Realm支持,就像Date一样。
答案 2 :(得分:0)
我所做的就是长期存储
我在我的应用程序中定义了一个常量:
public static final BigDecimal MONEY_PRECISION = new BigDecimal(1000);
当我需要存储一个大小数时,它会像这样:
public class MoneyClass extends RealmObject {
long _price = 0;
public void set_price(BigDecimal price) {
this._price = price.longValue() * App.MONEY_PRECISION.longValue();
}
public BigDecimal get_price() {
return new BigDecimal(_price).divide(App.MONEY_PRECISION, 0, 0);
}
}
从理论上讲,这应该比将其保存在字符串上更快,但我还没有真正看过领域代码
答案 3 :(得分:0)
我的解决方案:
定义界面:
public interface RealmConvert {
void convertToDB();
void convertToObj();
}
定义实体:
@Ignore
private BigDecimal balance;
private String balanceStr;
@Override public void convertToDB() {
if (getBalance() != null) {
setBalanceStr(getBalance().toString());
}
}
@Override public void convertToObj() {
if (getBalanceStr() != null) {
setBalance(new BigDecimal(getBalanceStr()));
}
}
在copyToRealm:call方法convertToDB之前
当您需要使用实体时:调用方法convert obj
这不是一个优雅的解决方案,但它可以工作。
Christian Melchior的答案在我的应用中不起作用。