1.redis本身不提供 msetex命令(批量增加key并设置过期时间)

class RedisExtend {
private static final Logger logger = LoggerFactory.getLogger(RedisExtend.class);
private static final int Port = 6379;
private static final String Host = "192.168.1.1";
private static final String PASS_WORD = "1234";
private static Jedis instance;
/**
* Lua脚本(msetex)
*/
private static final String LUA_SCRIPT_MSETEX = "local keysLen = table.getn(KEYS);" +
"local argvLen = table.getn(ARGV);" +
"local idx=1;" +
"local argVIdx=1;" +
"for idx=1,keysLen,1 do " +
"argVIdx=(idx-1)*2+1; " +
"redis.call('Set',KEYS[idx],ARGV[argVIdx],'EX',ARGV[argVIdx+1]);" +
"end " +
"return keysLen;"; private static String LUA_SCRIPT_MSETEX_SHA1; /**
* Lua脚本 (获取后删除)
*/
private static final String LUA_SCRIPT_GET_AND_DELETE =
"local current = redis.call('get', KEYS[1]);\n" +
"if (current) then\n" +
" redis.call('del', KEYS[1]);\n" +
"end\n" +
"return current;";
private static String LUA_SCRIPT_GET_AND_DELETE_SHA1; static {
LUA_SCRIPT_MSETEX_SHA1 = SHA1.encode(LUA_SCRIPT_MSETEX);
LUA_SCRIPT_GET_AND_DELETE_SHA1 = SHA1.encode(LUA_SCRIPT_GET_AND_DELETE);
} public static Jedis getInstance() {
if (instance == null) {
instance = initJedisLite().getTemplate().getJedisPool().getResource();
}
return instance;
} private static JedisLite initJedisLite() {
return new JedisLite(Host, Port);
} private static JedisTemplate jedisTemplate = initJedisLite().getTemplate(); public static long msetex(List<RedisKeyValue> redisKeyValues) {
if (CollectionUtils.isEmpty(redisKeyValues)) {
return 0;
} int keyCount = redisKeyValues.size();
List<String> param = new ArrayList<>(keyCount * 3);
for (RedisKeyValue item : redisKeyValues) {
Assert.notNull(item, "KeyValue不允许为空");
Assert.hasLength(item.getKey(), "Key不允许为空");
param.add(item.getKey());
} for (RedisKeyValue item : redisKeyValues) {
param.add(item.getValue());
param.add(Integer.toString(item.getSeconds()));
}
String[] paramArr = new String[param.size()];
param.toArray(paramArr);
return execLunaScript(new RedisScript(LUA_SCRIPT_MSETEX, LUA_SCRIPT_MSETEX_SHA1), keyCount, paramArr,
(o) -> (long) (o == null ? 0L : Integer.parseInt(o.toString())));
} public static String getdel(String key) {
return execLunaScript(new RedisScript(LUA_SCRIPT_GET_AND_DELETE, LUA_SCRIPT_GET_AND_DELETE_SHA1), 1, new String[]{key},
(o) -> (o == null ? null : o.toString()));
} private static <T> T execLunaScript(RedisScript redisScriptObj, int keyCount, String[] param,
Function<Object, T> function) {
try {
return jedisTemplate.execute((Jedis jedis) -> function.apply(jedis.evalsha(redisScriptObj.sha1, keyCount,
param)));
} catch (redis.clients.jedis.exceptions.JedisNoScriptException ex) {
return jedisTemplate.execute((Jedis jedis) -> function.apply(jedis.eval(redisScriptObj.script, keyCount,
param)));
} catch (Exception ex) {
logger.error("执行redis脚本异常!", ex);
return null;
}
} static class RedisScript {
private String script;
private String sha1; public RedisScript(String script) {
this(script, SHA1.encode(script));
} public RedisScript(String script, String sha1) {
this.script = script;
this.sha1 = sha1;
}
} static class RedisKeyValue {
private String key;
private String value;
private int seconds; public RedisKeyValue(String key, String value) {
this(key, value, -1);
} public RedisKeyValue(String key, String value, int seconds) {
this.key = key;
this.value = value;
this.seconds = seconds;
} public String getKey() {
return key;
} public String getValue() {
return value;
} public int getSeconds() {
return seconds;
}
}
}

2.调用代码如下

    public static void main(String[] args) {
long r = msetex(
Arrays.asList(new RedisKeyValue("key1", "value1", 5000),
new RedisKeyValue("key2", "value2", 5000),
new RedisKeyValue("ke3", "value3", 5000)
));
System.out.println("返回值:" + r); String key1Val = getdel("key1");
System.out.println("key1的值:" + key1Val);
key1Val = getdel("key1");
System.out.println("key1的值:" + key1Val);
}

3.返回结果如下

返回值:3
key1的值:value1
key1的值:null

4.sha1的代码如下

import java.security.MessageDigest;

public class SHA1 {
private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; /**
* Takes the raw bytes from the digest and formats them correct.
*
* @param bytes the raw bytes from the digest.
* @return the formatted bytes.
*/
private static String getFormattedText(byte[] bytes) {
int len = bytes.length;
StringBuilder buf = new StringBuilder(len * 2);
// 把密文转换成十六进制的字符串形式
for (int j = 0; j < len; j++) {
buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
}
return buf.toString();
} public static String encode(String str) {
if (str == null) {
return null;
}
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
messageDigest.update(str.getBytes());
return getFormattedText(messageDigest.digest());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

redis实现 msetex和 getdel命令的更多相关文章

  1. Redis数据结构及相应的命令

    Redis可以存储键(key)与5种不同类型值(value)之间的映射,5中不同类型的值分别为字符串(string),列表(list),散列(hash),集合(set)和有序集合(sorted set ...

  2. Redis 常用数据结构及其控制命令整合

    Redis 键值支持5种基本结构,分别是字符串,列表,哈希,集合,有序集合.每一种数据结构都有对应的取值和设值命令,辅助命令,除此之外,还有一些全局命令,用来管理Redis存储的所有 键. 全局命令 ...

  3. 使用控制台对Redis执行增删改查命令

    使用控制台对Redis执行增删改查命令 在上一篇里,我们已经安装了redis.这一篇我们将一起来学习如何使用"控制台"管理Redis 首先肯定是打开一个控制台,在windows系统 ...

  4. redis学习-集合set常用命令

    redis学习-集合set常用命令   1.sadd:添加一个元素到集合中(集合中的元素无序的并且唯一) 2.smembers:查看集合中所有的元素(上图事例) 3.srem:删除结合中指定的元素 4 ...

  5. redis学习-散列表常用命令(hash)

    redis学习-散列表常用命令(hash)   hset,hmset:给指定散列表插入一个或者多个键值对 hget,hmget:获取指定散列表一个或者多个键值对的值 hgetall:获取所欲哦键值以及 ...

  6. redis事务中的WATCH命令和基于CAS的乐观锁

    转自:http://blog.sina.com.cn/s/blog_ae8441630101cgy3.html 在Redis的事务中,WATCH命令可用于提供CAS(check-and-set)功能. ...

  7. Redis的增删改查命令总结与持久化方式

    原文:Redis的增删改查命令总结与持久化方式 Redis是用C语言实现的,一般来说C语言实现的程序"距离"操作系统更近,执行速度相对会更快. Redis使用了单线程架构,预防了多 ...

  8. Redis bin目录和info命令

    1.Redis bin目录和info命令 概述: bin目录是说我们的redis的安装目录中的bin目录,里面存放着一些可执行文件 info命令会列出当前连接的Redis实例的所有指标信息 下面我就对 ...

  9. Redis 几个类型常用命令

    Redis 字符串(String) 下表列出了常用的 redis 字符串命令: 序号 命令及描述1 SET key value 设置指定 key 的值2 GET key 获取指定 key 的值.3 G ...

随机推荐

  1. SIP简介

    说明:以下内容来着之前下载的一份文档,现将概念部分摘录在BLog,如需要完整文档将放在文件中或留言. SIP简介,第1部分:SIP初探 时间:2006-04-07作者:Emmanuel Proulx浏 ...

  2. 那些原生的javascript APIs

    在前端开发的时候,我们往往会使用javascript 框架,使用框架的好处多多,提供的方便的操作函数,类继承机制,MV*等,让我们能够快速开发,然而我们应该清楚这些框架都是基于浏览器原生api的封装, ...

  3. NIOS II 软件程序固化的相关知识

    片上RAM和ROM的SOPC系统1.生成hex文件2.将hex文件添加到quartus工程中(添加qip文件)3.对工程进行全编译4.下载sof就可以看到程序运行5.将sof转换为jic文件,烧写到E ...

  4. 基于FPGA的XPT2046触摸控制器设计

    基于FPGA的XPT2046触摸控制器设计 小梅哥编写,未经许可,文章内容和所涉及代码不得用于其他商业销售的板卡 本实例所涉及代码均可通过向 xiaomeige_fpga@foxmail.com  发 ...

  5. JAVA并发设计模式学习笔记(一)—— JAVA多线程编程

    这个专题主要讨论并发编程的问题,所有的讨论都是基于JAVA语言的(因其独特的内存模型以及原生对多线程的支持能力),不过本文传达的是一种分析的思路,任何有经验的朋友都能很轻松地将其扩展到任何一门语言. ...

  6. hibernate缓存机制(转载)

    缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能.缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事 ...

  7. LightOJ 1098(均值不等式,整除分块玄学优化)

    We all know that any integer number n is divisible by 1 and n. That is why these two numbers are not ...

  8. 20、Semantic-UI之数据验证

    20.1 实现数据验证   在很多前端框架中都提供了数据验证的操作,比如jQuery的验证框架等,但是jQuery的验证框架js文件太多:在使用Semantic-UI框架的时候只需要导入semanti ...

  9. Linux Guard Service - 守护进程的作用、用途、父进程标识的特点

    让test2直接成为守护进程 [root@localhost 02]# cat test2.c //test2 #include<stdio.h> #include<unistd.h ...

  10. IntelliJ OpenCV 开发环境搭建

    Windows下的IntelliJ + OpenCV开发环境搭建 基于IntelliJ IDEA 15 和 OpenCV 3.1.0 1. 在OpenCV官网下载OpenCV安装程序,双击解压到目标目 ...