【问题标题】:Using Realm.io to store money values使用 Realm.io 存储货币价值
【发布时间】:2014-10-07 01:45:26
【问题描述】:

我开始在我正在编写的 Android 应用中使用 Realm.io。在我的一个数据对象中,我需要存储货币值。以前我在内部将值存储为 BigDecimal 值,然后在移入和移出数据库时也将其转换为双精度值。

我一直被告知,由于处理方式的原因,将货币值存储在 double 中是一个坏主意。 不幸的是,Realm.io 不支持 BigDecimal 对象的存储和检索。

编写我自己的扩展 RealmObject 的货币类并将其作为数据对象的成员变量保存的最佳解决方案是什么?

【问题讨论】:

  • xamarin 开发者也需要十进制!

标签: java android realm


【解决方案1】:

来自 Realm 的 Emanuele。

你是对的,使用浮点数或双精度数是一个的主意。

我们目前不支持 BigDecimal,在我们这样做之前,我们必须看看它与所有其他语言绑定的关系如何,因为我们希望领域文件在所有支持的平台上兼容。

Christian 的想法很好,但我认为与 String 之间的转换有点慢。如果您不需要 BigDecimal 的任意精度属性,则可以使用 long 并乘以/除以所需精度要求的因子。由于整数值是位压缩的,因此这也将在 Realm 文件的大小方面节省大量空间。

【讨论】:

    【解决方案2】:

    这可行,但如果对您当前的 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 一样。

    【讨论】:

    • 如何查询总和的值?
    【解决方案3】:

    我所做的就是把它保存多久

    我在我的应用程序中定义了一个常量,如下所示:

    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);
        }
    
    }
    

    理论上这应该比将它保存在字符串上要快,但我并没有真正看过领域代码

    【讨论】:

    • 确保只要 long 不溢出就可以了,否则如果它是一个非常大的整数,您可以将它分成两个 long,一个具有前 15 位数字,然后第二个具有其他 15 个
    【解决方案4】:

    我的解决方案:

    定义接口:

    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之前:调用方法convertToDB

    当需要使用实体时:调用方法convert obj

    这不是一个优雅的解决方案,但它确实有效。

    Christian Melchior 的回答在我的应用中不起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-16
      • 2017-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多