如何在ROOM DB中存储货币?

时间:2017-12-05 10:48:40

标签: android android-room

我有实体:

@Entity(tableName = "products")
public class Product{

    @PrimaryKey(autoGenerate = true)
    private Long id;

    @ColumnInfo(name = "amount")
    private BigDecimal amount;

我需要将它存储在Room DB中。我无法存储BigDecimal并创建转换器:

public static class Converters {
        @TypeConverter
        public BigDecimal fromString(String value) {
            return value == null ? null : new BigDecimal(value);
        }

        @TypeConverter
        public Double amountToString(BigDecimal bigDecimal) {
            if (bigDecimal == null) {
                return null;
            } else {
                return bigDecimal.doubleValue();
            }
        }
    }

并添加到列:

@TypeConverters(Converters.class)
    @ColumnInfo(name = "amount")
    private BigDecimal amount;

现在我将货币存储在双栏中。我想要summ totalcurrency的方法:

@Query("SELECT SUM(amount) FROM products")
LiveData<Double> totalSum();

但我认为这是不好的方式,因为转换时我会丢失一些值。

我的问题:如何在ROOM DB中输入货币?和返回方法

LiveData<BigDecimal> totalSum();

2 个答案:

答案 0 :(得分:3)

您可以长期存储您的价值。如果你有例如。 1.55序列化时将其乘以100并在db中存储长。当你反序列化从这个long创建BigDecimal并将其除以100

 public static class Converters {
        @TypeConverter
        public BigDecimal fromLong(Long value) {
            return value == null ? null : new BigDecimal(value).divide(new BigDecimal(100));
        }

        @TypeConverter
        public Long toLong(BigDecimal bigDecimal) {
            if (bigDecimal == null) {
                return null;
            } else {
                return bigDecimal.multiply(new BigDecimal(100)).longValue();
            }
        }
    }

答案 1 :(得分:0)

我在LongBigDecimal之间使用了StringBigDecimal转换器。

警告:通过这种方式,您不能在Room DB中使用SUMTOTAL或其他表达式。因为我的应用程序用途是使用多种货币,所以我手动检索数据并根据当前汇率进行计算。

class BigDecimalTypeConverter {

    @TypeConverter
    fun bigDecimalToString(input: BigDecimal?): String {
        return input?.toPlainString() ?: ""
    }

    @TypeConverter
    fun stringToBigDecimal(input: String?): BigDecimal {
        if (input.isNullOrBlank()) return BigDecimal.valueOf(0.0)
        return input.toBigDecimalOrNull() ?: BigDecimal.valueOf(0.0)
    }

}

如果只有一种货币,则可以使用Double代替String

class BigDecimalDoubleTypeConverter {

    @TypeConverter
    fun bigDecimalToDoubleinput: BigDecimal?): Double {
        return input?.toDoubleOrNull() ?: 0.0
    }

    @TypeConverter
    fun stringToBigDecimal(input: Double?): BigDecimal {
        if (input == null) return BigDecimal.ZERO
        return BigDecimal.valueOf(input) ?: BigDecimal.ZERO
    }

}

因此,您可以从Dao中检索SUMTOTAL,...:

@Query("SELECT SUM(transactions.amounts) FROM transactions WHERE transactions.timestamp >= :fromDateTimestamp")
fun getTotalAmount(fromDateTimestamp: Long): Double

希望有帮助!