一.前言
本文主要讲解如何设计一个不重复的自增编码简单实现,编码主体结构:前缀+中间时间戳+自增值,其中的主要技术栈包括:Java,Redis,示例:AJX202406140000001=》AJX202406140000002
二.实现原理
三.实现代码及过程
1.实现工具类
package cn.iocoder.ydtq.module.gas.check.util;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Date;
/**
* 最大编码工具类
*/
@Component
@Slf4j
public class MaxNoUtil {
// redis键名
private static String MAX_NO = "max_no:%s:%s";
@Resource
private StringRedisTemplate stringRedisTemplate;
private static Interner<String> lock = Interners.newWeakInterner();
/**
* 获取最大单编号
* AJX202406140000001
*
* @param type 编码类型
* @return
*/
public String getMaxNo(String type) {
String maxNo = "";// 最大编码:0000001
String prefix = "";// 前缀:AJX
String middle = DateUtil.format(new Date(), "yyyyMMdd");// 中间时间戳:20240614
Long increment;// redis自增值
// 使用谷歌的
synchronized (lock.intern(type + middle)) {
// 前缀:AJX20240614
prefix = type + middle;
// 获得最大自增值
increment = stringRedisTemplate.opsForValue().increment(formatKey(prefix));
// 设置过期时间:当天过期
stringRedisTemplate.expireAt(formatKey(prefix), Date.from(LocalDateTime.of(LocalDate.now(), LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant()));
// 补0
maxNo = String.format("%7d", increment).replace(" ", "0");
return prefix + maxNo;
}
}
private static String formatKey(String prefix) {
return String.format(MAX_NO, TenantContextHolder.getTenantId(), prefix);
}
}
四.总结
本文核心是教大家如何简单的实现生成不重复的自增编码,自增序列编码可以通过其他算法实现,其余部分可自行扩展。