生成固定前缀固定长度的不重复字符串使用方法(可用于生成电商系统中的订单号,出库单号等等)
第一个方法,需要用到Java自带的原子类
private final AtomicInteger currentNum = new AtomicInteger(0);
public String code(Long userId) {
// 简单加密
userId = userId * 2 + 88;
//原子自增,再对10000取模,不足4位的用0补充
// 出现重复的场景(几乎不可能):系统在1秒内产生10000+单,同时第n和第n+9999单为同一用户时
String numStr = String.format("%04d", currentNum.getAndIncrement() % 10000);
return prefix + Long.toHexString(userId) + numStr + StringUtil.dateToString(new Date(), "yyMMddHHmmss");
}
第二个方法,需要用到redis
public String nextCode(String bizCode) {
if (StringUtils.isNotBlank(this.redisHost)) {
String yyyyMMdd = LocalDateTime.now().format(DateTimeFormatter.BASIC_ISO_DATE);
String dateKey = RedisKeys.getPermsKey(bizCode + ":" + this.env + ":" + yyyyMMdd);
Long increment = this.stringRedisTemplate.opsForValue().increment(dateKey, 1L);
if (Objects.equals(1L, increment)) {
this.stringRedisTemplate.delete(RedisKeys.getPermsKey(bizCode + ":" + this.env + ":" + LocalDateTime.now().minusDays(1L).format(DateTimeFormatter.BASIC_ISO_DATE)));
}
return String.format(bizCode + yyyyMMdd + "%06d", increment);
} else {
throw new AppException("请先开启redis", "sys." + this.appExceptionHandler.getAppId() + ".500");
}
}