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. 深入理解yield-乾颐堂

    yield的英文单词意思是生产,刚接触Python的时候感到非常困惑,一直没弄明白yield的用法. 只是粗略的知道yield可以用来为一个函数返回值塞数据,比如下面的例子: 1 2 3 def ad ...

  2. 让你大开眼界的10款Android界面设计

    根据调查显示, iOS与Android的市场份额差距正越来越大.Android设备正在成为手机应用市场的主力军.如何从设计层面创造一个优美的app界面来吸引用户已然成为广大App开发者们必做的功课之一 ...

  3. Android canvas bug

    安卓4.1.1-4.1.2的webkit在渲染canvas元素时有bug. 具体表现是出现重影,即canvas的clearRect()方法不能彻底清空画布,仍然保留之前某个状态当“背景”. 目前的修复 ...

  4. thinkphp5网站中集成使用支付宝手机支付接口

    今天以thinkphp5中使用支付宝的手机支付接口为例. 一.创建基本页面pay/alipay_wap_submit.php(开始创建订单) <!DOCTYPE html> <htm ...

  5. 搭建python+PyQt+Eric平台

    搭建python+PyQt+Eric平台 预备安装程序: 2.1.下载Python3.2 官方网站:http://www.python.org/ 下载地址:http://www.python.org/ ...

  6. APUE(5)---标准I/O库 (1)

    一.引言 标准I/O库不仅是UNIX,许多i其他操作系统都实现了标准I/O库,所以这个库由ISO C标准说明.标准I/O库处理很多细节,如缓冲区分配,以及优化的块长度执行I/O等.这使得它便于用户使用 ...

  7. kafka的api操作(官网http://kafka.apache.org/documentation/#producerapi)

    Kafka API 简单用法 本篇会用到以下依赖:(本人包和这个不同,去maven里查找) <dependency><groupId>org.apache.kafka</ ...

  8. CodeSmith Generator 6.5 自动生成后的源码分析

    1,NetTiers代码结构流程分析: 2,CodeSmithNetTiers使用实践总结 参看流程结构图和实体定义文件关系图,可以看出自动代码生成后,若是手工来调,还是很麻烦的.鉴于此,建议:1,若 ...

  9. dubbo 安装部署

    dubbo 安装部署   1 安装zookeeper 2 安装dubbo    1 下载源码 https://github.com/alibaba/dubbo 2 编译 mvn clean packa ...

  10. orcal 锁表

    --查询Oracle正在执行的sql语句及执行该语句的用户 SELECT b.sid oracleID, b.username 登录Oracle用户名, b.serial#, spid 操作系统ID, ...