分享Redis中处理高精度BigDecimal数据

2024-12-09  本文已影响0人  wds_94

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);
    }
上一篇 下一篇

猜你喜欢

热点阅读