首頁 > 軟體

使用redis如何生成自增序列號碼

2022-11-25 14:01:32

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();
    }
}

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com