需求:
在数据库中,某个字段需要根据规则生成唯一的字段。格式:TK+年+月+日+0000(从001开始递增),例如:TK202404200001。
所以我们自己手写一个代码来生成对应的code,并且自增。下面的代码先定义了几个固定的字段,例如前缀TK,以及redis里面的key(redis可替换成自己的可以即可),存在redis里面主要是为了快速获取最新的值,并且唯一性。然后根据获取的值+1处理,再把前缀拼接起来,就组成了一个唯一的id。
而且还要根据redis里面的值判断是不是今天的,如果不是今天的,就从0001开始递增。
java">/**根据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;}
这个完全可以做成一个工具类来实现,就是要固定的格式,所以进阶版本如下代码。
进阶版本:
java"> /**** 根据自定义的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,太耗时了,需要开线程来处理,这部分后面再聊。