1.编写lua脚本用于生成主键ID序列号,内容如下

local key = tostring(KEYS[1]);
local count = tonumber(KEYS[2]);
local dateStr = tostring(KEYS[3]); local newKey = key .. "_" .. dateStr;
local numRedis = redis.call("incr", newKey);
print(numRedis); if (numRedis == 1) then
redis.call("expire",newKey,60);
end -- 计算数字的位数
local function DightNum(num)
if math.floor(num) ~= num or num < 0 then
return -1;
elseif 0 == num then
return 1;
else
local tmp_dight = 0;
while num > 0 do
num = math.floor(num/10);
tmp_dight = tmp_dight + 1;
end
return tmp_dight;
end
end -- 在整数数字前面加0
-- dest_dight 标识最终生成位数,例如 AddZeroFrontNum(5, 1) 计算后是00001
local function AddZeroFrontNum(dest_dight, num)
local num_dight = DightNum(num);
if -1 == num_dight then
return -1;
elseif dest_dight <= num_dight then
return tostring(num);
else
local str_e = ""
for var =1, dest_dight - num_dight do
str_e = str_e .. "0";
end
return str_e .. tostring(num);
end
end local idStr = AddZeroFrontNum(count, numRedis);
return dateStr .. idStr;

2.redis加载lua脚本文件

redis-cli -a redis script load "$(cat getGenerateId.lua)"
"b3d58fe8b47b1ca1e1fb074db5c3506a09ffdae8"

-a: redis密码,如果没有密码,该项不需要输入

下面的字符串即为加载后redis保存的sha值,通过该sha值可以访问lua脚本

3.java代码执行缓存的lua脚本文件

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis; import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
@Service
public class RedisService { private static final DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
@Autowired
private RedisTemplate<String, String> redisTemplate; public Object executeScript(final String sha, final List<String> keys, final ArrayList<String> vals) {
return redisTemplate.execute(new RedisCallback() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
Jedis jedis = (Jedis) connection.getNativeConnection();
return jedis.evalsha(sha, keys, vals);
}
}, true);
} /**
* 每秒从 1 开始生成唯一标识,包括时间戳:yyyyMMddHHmmss
* 最终格式为:yyyyMMddHHmmss + 四位有序数字
* @param sha redis中生成lua脚本的序列号
* @param key redis中存放id的key前缀
* @param length 后面生成有序数字的位数
* @return
*/
public Long fetchUUID(String sha, String key, String length){
List<String> keys = new ArrayList<>();
keys.add(key);
keys.add(length);
Calendar now = new GregorianCalendar();
String datetime = df.format(now.getTime());
keys.add(datetime);
Object obj = executeScript(sha, keys, new ArrayList<String>());
return Long.parseLong(String.valueOf(obj));
}
}

然后调用fetchUUID该方法就可以了,key和length自定义,sha为第二步生成值

java+redis+lua生成自动增长的ID序列号的更多相关文章

  1. SQL获取刚插入的记录的自动增长列ID的值

    假设表结构如下: CREATE TABLE TestTable ( id int identity, CreatedDate datetime ) SQL2005获得新增行的自动增长列的语句如下: i ...

  2. 使用强类型DataSet增加数据并获取自动增长的ID

    使用强类型的DataSet可以方便的操作数据库:有时候我们会对表的ID设置为自动增长,并且需要在插入数据后获取新插入数据的ID,按以下方法即可达到目的: 一.     首先建立一个表,id为自动增加, ...

  3. 使用JDBC获取SQL自动增长的ID

    在项目开发中,遇到一个问题,先添加一条记录然后想立刻获取这条记录的ID值,ID由SQLServer自动增长的,如果先插入再查询的话,需要另外执行一条查询ID的SQL语句,因此有了下面的方法: 1.使用 ...

  4. sql server生成自动增长的字母数字字符串

    在开发的过程中,我们经常会遇到要生成一些固定格式字符串,例如“BX201903150001”,结构为:BX+日期+N位序号,类似这种的字符串我们很难生成,在这里我们借助一个存储过程来实现这个功能. 1 ...

  5. 写出一条Sql语句:取出表A中第31到第40记录(SQLServer,以自动增长的ID作为主键,注意:ID可能不是连续的。

    答:解1:  select top 10 * from A where id not in (select top 30 id from A) 解2:  select top 10 * from A ...

  6. 写出一条Sql语句:取出表Customer中第31到第40记录(SQLServer,以自动增长的Id作为主键,注意:Id可能不是连续的。

    select top 10 * from (select ROW_NUMBER() over(order by Id) as rows,* from Customer) as C where C.ro ...

  7. oracle 12c之前用sequence 和 trigger来生成自动增长的列

    SQL> create table scott.t1 (id number, val varchar2(8)); Table created. SQL> CREATE SEQUENCE s ...

  8. java项目实现流水号自动增长

    项目中有一个规则编号字段,从1开始,编号长度为5位,那么第一条数据编号就是00001. 实现的基本思路就是项目启动时,从数据库获取当前最大值,作为静态变量存储: 业务获取新的编码,考虑并发问题,获取编 ...

  9. spring boot:redis+lua实现顺序自增的唯一id发号器(spring boot 2.3.1)

    一,为什么需要生成唯一id(发号器)? 1,在分布式和微服务系统中, 生成唯一id相对困难, 常用的方式: uuid不具备可读性,作为主键存储时性能也不够好, mysql的主键,在分库时使用不够方便, ...

随机推荐

  1. [C++][转]CPU字节序 网络序 主机序 大端小端

    原帖:http://www.cnblogs.com/darktime/p/3298075.html 不同的CPU有不同的字节序类型 这些字节序是指整数在内存中保存的顺序 这个叫做主机序最常见的有两种1 ...

  2. 牛客网剑指offer java 全部题解

    经过数月的努力,终于更完了牛客网的66道剑指offer,以下的顺序和大家在牛客网的顺序是一样的(排序也花了不少时间),希望对大家找工作/提高算法能力能起到些许帮助. 每天一道剑指offer-二维数组中 ...

  3. 二进制转化、<<、>>、>>>移位运算

    参考资料: https://www.cnblogs.com/wxb20/p/6033458.html https://www.cnblogs.com/joahyau/p/6420619.html ht ...

  4. Java基础教程(21)--泛型

    一.为什么使用泛型   泛型意味着编写的代码可以被很多不同类型的对象所重用.例如,我们不希望为存放String和Integer对象的集合设计不同的类.现在的ArrayList类可以存放任何类型的对象, ...

  5. 《码出高效 Java开发手册》第六章 数据结构与集合

    码云: https://gitee.com/forxiaoming/JavaBaseCode/blob/master/EasyCoding/src/collection/index.md 6.1 数据 ...

  6. 【基于初学者的SSH】struts2 的拦截器、令牌的简单应用及理解

    一:拦截器与过滤器类似,但是它们的区别也很大: 01):过滤器理论上可以过滤任意内容,比如HTML,servlet,jsp,图片路径 02):拦截器只可以拦截action. 二:拦截器的原理  act ...

  7. Linux CPU使用率的计算

         CPU 使用率衡量的是程序运行占用的CPU 百分比.Linux 的CPU 使用率信息可以通过/proc/stat 文件计算得到. proc 文件系统       /proc 文件系统是一个伪 ...

  8. ECMAScript 5和ECMAScript6的新特性以及浏览器支持情况

    ECMAScript简介: 它是一种由Ecma国际(前身为欧洲计算机制造商协会)制定和发布的脚本语言规范,javascript在它基础上经行了自己的封装.但通常来说,术语ECMAScript和java ...

  9. 通过读写文本文件小结“关于python处理中文编码的问题”

    一.引言 无论学习什么程序语言,字符串这种数据类型总是着有非常重要.然而最近在学习python这门语言,想要显示中文,总是出现各种乱码.于是在网上查了很多资料,各说纷纭,我也尝试了许多的方法,有时候可 ...

  10. Javascript中的bind详解

    前言 用过React的同学都知道,经常会使用bind来绑定this. import React, { Component } from 'react'; class TodoItem extends ...