如何使用redis生成唯一编号及原理
以SpringBoot项目为例,添加以下依赖
1 2 3 4 5 6 7 8 9 10 | <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version> 3.1 </version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>${spring.boot.version}</version> </dependency> |
application.properties中配置redis,我本地redis没有设置密码,所以注释了密码这一行
1 2 3 4 5 6 7 | server.port= 9091 server.servlet.context-path=/ spring.redis.host= 127.0 . 0.1 spring.redis.port= 6379 #spring.redis.password= 1234 spring.redis.database= 0 |
创建SequenceService类用于生成特定业务编号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.support.atomic.RedisAtomicLong; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; @Service public class SequenceService { private static Logger logger = LoggerFactory.getLogger(SequenceService. class ); @Resource private RedisTemplate redisTemplate; //用作存放redis中的key private static String ORDER_KEY = "order_key" ; //生成特定的业务编号,prefix为特定的业务代码 public String getOrderNo(String prefix){ return getSeqNo(ORDER_KEY, prefix); } //SequenceService类中公用部分,传入制定的key和prefix private String getSeqNo(String key, String prefix) { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, 23 ); calendar.set(Calendar.MINUTE, 59 ); calendar.set(Calendar.SECOND, 59 ); calendar.set(Calendar.MILLISECOND, 999 ); //设置过期时间,这里设置为当天的23:59:59 Date expireDate = calendar.getTime(); //返回当前redis中的key的最大值 Long seq = generate(redisTemplate, key, expireDate); //获取当天的日期,格式为yyyyMMdd String date = new SimpleDateFormat( "yyyyMMdd" ).format(expireDate); //生成八为的序列号,如果seq不够八位,seq前面补0, //如果seq位数超过了八位,那么无需补0直接返回当前的seq String sequence = StringUtils.leftPad(seq.toString(), 8 , "0" ); if (prefix == null ) { prefix = "" ; } //拼接业务编号 String seqNo = prefix + date + sequence; logger.info( "KEY:{}, 序列号生成:{}, 过期时间:{}" , key, seqNo, String.format( "%tF %tT " , expireDate, expireDate)); return seqNo; } /** * @param key * @param expireTime <i>过期时间</i> * @return */ public static long generate(RedisTemplate<?,?> redisTemplate,String key,Date expireTime) { //RedisAtomicLong为原子类,根据传入的key和redis链接工厂创建原子类 RedisAtomicLong counter = new RedisAtomicLong(key,redisTemplate.getConnectionFactory()); //设置过期时间 counter.expireAt(expireTime); //返回redis中key的值,内部实现下面详细说明 return counter.incrementAndGet(); } } |
参考链接:https://www.cnblogs.com/dsxie/p/13324489.html
nnjk
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类