BigDecimal是什么?
BigDecimal在java的文档中介绍特别长,但是对于开发者来说,你只需要知道这个是用来处理高精度数据,高精度多高算高呢?超过double的极限即16位小数。
Redis中如何存储BigDecimal
首先,Redis是不支持高精度数据存储的,浮点数最多支持到双精度即16位小数。所以BigDecimal数据想要再Redis中存储有两种方式
1.转成字符串进行存储
BigDecimal有一个方法为toPlainString() ,直接使用这个存储为String。
/**
* 保存BigDecimal
*
* @param amount 入金金额
*/
@Override
public void saveBigDecimal(BigDecimal amount) {
String orderDayKey = String.format(ORDER_DAY_USER, dayCode);
if (Boolean.FALSE.equals(redisTemplate.hasKey(orderDayKey))) {
redisTemplate.opsForValue().set(orderDayKey, amount.toPlainString());
}
BigDecimal orderSum = new BigDecimal(redisTemplate.opsForValue().get(orderDayKey));
redisTemplate.opsForValue().set(orderDayKey, orderSum.add(amount).toPlainString());
}
2.转成长整型进行存储
将浮点数乘以10的精度次方 例如需要存储数据为2.2100,精度为4,可以先将数据转化为2.2100*10^4 = 22100, 存在redis的就是这个长整型 22100.
取值时做反向操作除以10^精度
/**
* 保存BigDecimal
*
* @param amount 金额
* @param showPrecision 精度
*/
@Override
public void saveBigDecimal(BigDecimal amount, Integer showPrecision) {
showPrecision = Objects.isNull(showPrecision) ? 4 : showPrecision;
String dayCode = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
String depositDayKey = String.format(AccountRedisKeyConstants.DEPOSIT_DAY_USER, dayCode);
long amountInCents = amount.multiply(BigDecimal.TEN.pow(showPrecision)).longValue();
redisTemplate.opsForValue().increment(depositDayKey, amountInCents);
}
/**
* 查询BigDecimal
*
* @param showPrecision 精度
*/
public BigDecimal getBigDecimal(Integer showPrecision) {
showPrecision = Objects.isNull(showPrecision) ? 4 : showPrecision;
String depositDayKey = String.format(AccountRedisKeyConstants.DEPOSIT_DAY_USER, dayCode, uid);
String value = redisTemplate.opsForValue().get(depositDayKey);
if (StringUtils.isBlank(value)) {
return BigDecimal.ZERO;
}
return new BigDecimal(value).divide(BigDecimal.TEN.pow(showPrecision), showPrecision, RoundingMode.DOWN);
}








网友评论