使用redis如何生成自增序列號(hào)碼
redis生成自增序列號(hào)碼
導(dǎo)入依賴
<!--redis--> <dependency> ?? ?<groupId>org.springframework.boot</groupId> ?? ??? ?<artifactId>spring-boot-starter-data-redis</artifactId> ?? ??? ?<exclusion> ?? ?<groupId>org.springframework.boot</groupId> ?? ?<artifactId>spring-boot-starter-logging</artifactId> ?? ?</exclusion> ?? ?</exclusions> </dependency>
yml 配置
? redis: ? ? ? database: 10 ? ? ? host: localhost ? ? ? port: 7701 ? ? ? password: root
工具方法
package com.sd.sdactivity.controller; import io.netty.util.internal.StringUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; /** ?* 使用redis生成自增序列 ?*/ @RestController public class testController { @Autowired private StringRedisTemplate redisTemplate; ? ? /** ? ? ?* 自增序列號(hào) ? ? ?* @param prefix ?前綴 ? ? ?* @param numLength ?要生成多少位數(shù)字 ? ? ?* @return ? ? ?*/? @RequestMapping("/SeqGenerator") ? ? public String SeqGenerator(String prefix,int numLength){ ? ? ? ? String upperCode =""; ?? ? ?Long size=redisTemplate.opsForList().size(prefix);//查找 prefix 的key值的數(shù)據(jù)長(zhǎng)度 ? ? ? ? if(size>0){//有數(shù)據(jù) List leve =redisTemplate.opsForList().range(prefix,0,-1);//獲取該key下面的所有值(-1 所有的值,;1下一個(gè)值 ? upperCode=leve.get(leve.size()-1).toString();//返回最后一個(gè)值 ? ? ? ? } ? ? ? ? ? ?String returnCode=""; ? ? ? ? ? int Suffix; ?//后綴數(shù)字 if (!StringUtil.isNullOrEmpty(upperCode)){ //有數(shù)據(jù) ? ? ? ? ? ? String sequence =upperCode.substring(prefix.length());//截取前綴開始的后面的數(shù)字 ? ? ? ? ? ? Suffix=Integer.parseInt(sequence);? ? ? ? ? ? ? ?Suffix++;//最后的序號(hào)加一 ? ? ? ? ?}else{ ? ? ? ? ? ? Suffix=1;//沒有數(shù)據(jù) ? ? ? ? } ? ? ? ? ? ?returnCode=prefix+String.format("%0"+numLength+"d",Suffix);//后綴不夠numLength長(zhǎng),前面補(bǔ)充0 ? ? ? ? redisTemplate.opsForList().rightPush(prefix,returnCode);//存入Redis ? ? ? ? System.out.println(returnCode+"%%%"); ? ? ? ? return ?returnCode; ? } }
測(cè)試
2020-05-13 11:43:31.230 INFO 39268 --- [ main] c.f.SpringbootRedisApplicationTests : seq00000002
redis生成唯一編號(hào)
在系統(tǒng)開發(fā)中,保證數(shù)據(jù)的唯一性是至關(guān)重要的一件事,目前開發(fā)中常用的方式有使用數(shù)據(jù)庫的自增序列、UUID、時(shí)間戳或者時(shí)間戳+隨機(jī)數(shù)等。
因?yàn)镽edis是原子性的,所以我們可以用redis生成一個(gè)唯一的號(hào)碼,記錄一個(gè)編號(hào),我們用這個(gè)編號(hào)可以配合時(shí)間戳生成一個(gè)唯一的key
接下來是上代碼
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; /** * 使用redis生成唯一key */ @Service("reportNumberUtils") public class ReportNumberUtils { private static Logger logger = LoggerFactory.getLogger(ReportNumberUtils.class); @Resource private RedisTemplate redisTemplate; //傳入制定的key和prefix public 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); //設(shè)置過期時(shí)間,這里設(shè)置為當(dāng)天的23:59:59 Date expireDate = calendar.getTime(); //返回當(dāng)前redis中的key的最大值 Long seq = generate(redisTemplate, key, expireDate); //獲取當(dāng)天的日期,格式為yyyyMMdd String date = new SimpleDateFormat("yyyyMMdd").format(expireDate); //生成八為的序列號(hào),如果seq不夠八位,seq前面補(bǔ)0, //如果seq位數(shù)超過了八位,那么無需補(bǔ)0直接返回當(dāng)前的seq String sequence = StringUtils.leftPad(seq.toString(), 8, "0"); if (prefix == null) { prefix = ""; } //拼接業(yè)務(wù)編號(hào) String seqNo = prefix + date + sequence; logger.info("KEY:{}, 序列號(hào)生成:{}, 過期時(shí)間:{}", key, seqNo, String.format("%tF %tT ", expireDate, expireDate)); return seqNo; } /** * @param key * @param expireTime <i>過期時(shí)間</i> * @return */ public static long generate(RedisTemplate<?,?> redisTemplate,String key,Date expireTime) { //RedisAtomicLong為原子類,根據(jù)傳入的key和redis鏈接工廠創(chuàng)建原子類 RedisAtomicLong counter = new RedisAtomicLong(key,redisTemplate.getConnectionFactory()); //設(shè)置過期時(shí)間 counter.expireAt(expireTime); //返回redis中key的值,內(nèi)部實(shí)現(xiàn)下面詳細(xì)說明 return counter.incrementAndGet(); } }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Redis從單點(diǎn)到集群部署模式(單機(jī)模式?主從模式?哨兵模式)
這篇文章主要為大家介紹了Redis從單點(diǎn)集群部署模式(單機(jī)模式?主從模式?哨兵模式)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11基于Redis過期事件實(shí)現(xiàn)訂單超時(shí)取消
這篇文章主要介紹了基于Redis過期事件實(shí)現(xiàn)訂單超時(shí)取消,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05redis哈希類型_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了redis哈希類型的常用方法及原理淺析,感興趣的朋友一起看看吧2017-08-08淺談redis采用不同內(nèi)存分配器tcmalloc和jemalloc
下面小編就為大家?guī)硪黄獪\談redis采用不同內(nèi)存分配器tcmalloc和jemalloc。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-12-12用Redis實(shí)現(xiàn)微博關(guān)注關(guān)系
在微博中,每一個(gè)用戶都會(huì)有一個(gè)關(guān)注列表,一個(gè)粉絲列表。用戶可以查看自己的關(guān)注,粉絲列表,也可以查看別人的關(guān)注,粉絲列表。并且,要展示列表里每個(gè)人與當(dāng)前查看者的關(guān)注狀態(tài)。2015-09-09為什么RedisCluster設(shè)計(jì)成16384個(gè)槽
本文主要介紹了為什么RedisCluster設(shè)計(jì)成16384個(gè)槽,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09Redisson實(shí)現(xiàn)分布式鎖、鎖續(xù)約的案例
這篇文章主要介紹了Redisson如何實(shí)現(xiàn)分布式鎖、鎖續(xù)約,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03