使用redis如何生成自增序列号码
作者:饭团小哥哥iop
这篇文章主要介绍了使用redis如何生成自增序列号码,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
redis生成自增序列号码
导入依赖
<!--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; /** * 自增序列号 * @param prefix 前缀 * @param numLength 要生成多少位数字 * @return */ @RequestMapping("/SeqGenerator") public String SeqGenerator(String prefix,int numLength){ String upperCode =""; Long size=redisTemplate.opsForList().size(prefix);//查找 prefix 的key值的数据长度 if(size>0){//有数据 List leve =redisTemplate.opsForList().range(prefix,0,-1);//获取该key下面的所有值(-1 所有的值,;1下一个值 upperCode=leve.get(leve.size()-1).toString();//返回最后一个值 } String returnCode=""; int Suffix; //后缀数字 if (!StringUtil.isNullOrEmpty(upperCode)){ //有数据 String sequence =upperCode.substring(prefix.length());//截取前缀开始的后面的数字 Suffix=Integer.parseInt(sequence); Suffix++;//最后的序号加一 }else{ Suffix=1;//没有数据 } returnCode=prefix+String.format("%0"+numLength+"d",Suffix);//后缀不够numLength长,前面补充0 redisTemplate.opsForList().rightPush(prefix,returnCode);//存入Redis System.out.println(returnCode+"%%%"); return returnCode; } }
测试
2020-05-13 11:43:31.230 INFO 39268 --- [ main] c.f.SpringbootRedisApplicationTests : seq00000002
redis生成唯一编号
在系统开发中,保证数据的唯一性是至关重要的一件事,目前开发中常用的方式有使用数据库的自增序列、UUID、时间戳或者时间戳+随机数等。
因为Redis是原子性的,所以我们可以用redis生成一个唯一的号码,记录一个编号,我们用这个编号可以配合时间戳生成一个唯一的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); //设置过期时间,这里设置为当天的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(); } }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。