使用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());//截取前綴開(kāi)始的后面的數(shù)字
? ? ? ? ? ? Suffix=Integer.parseInt(sequence);?
? ? ? ? ? ? ?Suffix++;//最后的序號(hào)加一
? ? ? ? ?}else{
? ? ? ? ? ? Suffix=1;//沒(méi)有數(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)開(kāi)發(fā)中,保證數(shù)據(jù)的唯一性是至關(guān)重要的一件事,目前開(kāi)發(fā)中常用的方式有使用數(shù)據(jù)庫(kù)的自增序列、UUID、時(shí)間戳或者時(shí)間戳+隨機(jī)數(shù)等。
因?yàn)镽edis是原子性的,所以我們可以用redis生成一個(gè)唯一的號(hào)碼,記錄一個(gè)編號(hào),我們用這個(gè)編號(hào)可以配合時(shí)間戳生成一個(gè)唯一的key
接下來(lái)是上代碼
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è)置過(guò)期時(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ù)超過(guò)了八位,那么無(wú)需補(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)生成:{}, 過(guò)期時(shí)間:{}", key, seqNo, String.format("%tF %tT ", expireDate, expireDate));
return seqNo;
}
/**
* @param key
* @param expireTime <i>過(guò)期時(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è)置過(guò)期時(shí)間
counter.expireAt(expireTime);
//返回redis中key的值,內(nèi)部實(shí)現(xiàn)下面詳細(xì)說(shuō)明
return counter.incrementAndGet();
}
}以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
解決redis服務(wù)啟動(dòng)失敗的問(wèn)題
今天小編就為大家分享一篇解決redis服務(wù)啟動(dòng)失敗的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
基于Redis的限流器的實(shí)現(xiàn)(示例講解)
下面小編就為大家分享一篇基于Redis的限流器的實(shí)現(xiàn)(示例講解),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
Redis常見(jiàn)限流算法原理及實(shí)現(xiàn)
這篇文章主要介紹了Redis常見(jiàn)限流算法原理及實(shí)現(xiàn),限流簡(jiǎn)稱流量限速(Rate?Limit)是指只允許指定的事件進(jìn)入系統(tǒng),超過(guò)的部分將被拒絕服務(wù)、排隊(duì)或等待、降級(jí)等處理2022-08-08
使用redis-plus-plus庫(kù)連接redis的實(shí)現(xiàn)方法
本文主要介紹了使用redis-plus-plus庫(kù)連接redis的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-02-02
Redis使用元素刪除的布隆過(guò)濾器來(lái)解決緩存穿透問(wèn)題

