spring生成递增key值

需求:
在数据库中,某个字段需要根据规则生成唯一的字段。格式:TK+年+月+日+0000(从001开始递增),例如:TK202404200001。

所以我们自己手写一个代码来生成对应的code,并且自增。下面的代码先定义了几个固定的字段,例如前缀TK,以及redis里面的key(redis可替换成自己的可以即可),存在redis里面主要是为了快速获取最新的值,并且唯一性。然后根据获取的值+1处理,再把前缀拼接起来,就组成了一个唯一的id。
而且还要根据redis里面的值判断是不是今天的,如果不是今天的,就从0001开始递增。

/**根据redis中有无缓存生成平台客户编码*/
    private String createTkCustomerCode(){
        String prefix = "TK";
        String CUSTOMER_CODE_KEY = "CUSTOMER_CODE_KEY";
        StringBuilder response = new StringBuilder();
        String today = DateUtils.getReqDateyyyyMMdd(new Date());
        String currentCustomerCode = redisHelper.strGet(CUSTOMER_CODE_KEY);
        if (!StringUtils.isEmpty(currentCustomerCode) && isToday(prefix, currentCustomerCode)){
            String number = currentCustomerCode.substring(currentCustomerCode.length() - 4);
            int value;
            try {
                 value = Integer.parseInt(number);
            } catch (Exception e) {
                Random random = new Random();
                value = random.nextInt(4999) + 4999;
            }
            int increaseValue = value + 1;
            String formatted = String.format("%04d", increaseValue);
            response.append(prefix).append(today).append(formatted);
            redisHelper.strSet(CUSTOMER_CODE_KEY, response.toString(),24, TimeUnit.HOURS);
            return response.toString();
        }
        //redis中无值
        response.append(prefix).append(today).append("0001");
        redisHelper.strSet(CUSTOMER_CODE_KEY, response.toString(),24, TimeUnit.HOURS);
        return response.toString();
    }

    /**判断是否是今天。eg:TK202404090001*/
    private boolean isToday(String prefix, String data){
        if (data.length() >= 14){
            String keyToday = data.substring(0,data.length() - 4).toUpperCase();
            String today = DateUtils.getCurrentDay("yyyyMMdd");
            return Objects.equals(keyToday, prefix + today);
        }
        return false;
    }

这个完全可以做成一个工具类来实现,就是要固定的格式,所以进阶版本如下代码。
进阶版本:

    /***
     * 根据自定义的prefix前缀,生成带时间戳的编码,输入编码前缀
     * 前缀+年月日+4位流水号
     *
     * @param redisKey redis的key
     * @param prefix 前缀
     * @return
     */
    public String getYYYYMMDD4Code(String redisKey, String prefix) {
        Long sequenceId = 1L;
        String reqDate = getReqDate();
        String redisName = redisKey + reqDate + prefix;
        if (redisHelper.strGet(redisName, Long.class) == null) {
            redisHelper.strSet(redisName, String.valueOf(sequenceId), getNowToNextDayMilliSeconds(), TimeUnit.SECONDS);//redisHelper替换成自己的redis即可
        } else {
            sequenceId = redisHelper.strIncrement(redisName, 1L);
        }

        DecimalFormat format = new DecimalFormat("0000");
        return prefix + reqDate + format.format(sequenceId);流水号
    }
    private final String YYYY_MM_DD_HH_MM_CODE_KEY = "business:app:YYYY_MM_DD_HH_MM_CODE_KEY:";

/**
     * 生成带时间戳的编码,输入编码前缀
     * 前缀+年月日时分+6位流水号
     */
    public String getYYYYMMddHHmm6Code(String prefix) {
        Long sequenceId = 1L;
        String reqDate = new SimpleDateFormat("yyyyMMddHHmm").format(new Date());
        String redisName = YYYY_MM_DD_HH_MM_CODE_KEY + reqDate + prefix;
        if (redisHelper.strGet(redisName, Long.class) == null) {
            redisHelper.strSet(redisName, String.valueOf(sequenceId), getNowToNextDayMilliSeconds(), TimeUnit.SECONDS);
        } else {
            sequenceId = redisHelper.strIncrement(redisName, 1L);
        }

        DecimalFormat format = new DecimalFormat("000000");
        return prefix + reqDate + format.format(sequenceId);
    }
    
	public String getReqDate() {//yyyy-MM-dd 当前日期
		return new SimpleDateFormat("yyyyMMdd").format(new Date());
	}

但是这里还有一个问题,批量操作现有的数据,如果在单个线程里面操作,数据有5912条都需要530s,太耗时了,需要开线程来处理,这部分后面再聊。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值