I have entity:
@Entity(tableName = "products")
public class Product{
@PrimaryKey(autoGenerate = true)
private Long id;
@ColumnInfo(name = "amount")
private BigDecimal amount;
I need store it in Room DB. I Can not store BigDecimal
and I create converter:
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();
}
}
}
and add to column:
@TypeConverters(Converters.class)
@ColumnInfo(name = "amount")
private BigDecimal amount;
Now I store currency in double column. And I want method for summ totalcurrency:
@Query("SELECT SUM(amount) FROM products")
LiveData<Double> totalSum();
But I think it is bad way, because I can lose some values when converting.
My question: How can I ctore currency in ROOM DB? and return method
LiveData<BigDecimal> totalSum();
Room is one of the Jetpack Architecture Components in Android. This provides an abstract layer over the SQLite Database to save and perform the operations on persistent data locally.
3.1 Add the Clear all data menu option In MainActivity , implement the onOptionsItemSelected() method to invoke the deleteAll() method on the WordViewModel object. Run your app. In the Options menu, select Clear all data. All words should disappear.
Instead of Long
vs BigDecimal
converters, I'm using between String
and BigDecimal
.
Warning: With this way, you can't use SUM
, TOTAL
or other expression with Room DB. Because my purpose for app is using many currencies, so I manually retrieve data and calculate based on current exchange rates.
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)
}
}
if you only have one currency, you can use Double
instead of 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
}
}
So you can retrieve SUM
, TOTAL
,... from Dao:
@Query("SELECT SUM(transactions.amounts) FROM transactions WHERE transactions.timestamp >= :fromDateTimestamp")
fun getTotalAmount(fromDateTimestamp: Long): Double
Hope it help!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With