redis实现 msetex和 getdel命令
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命令的更多相关文章
- Redis数据结构及相应的命令
Redis可以存储键(key)与5种不同类型值(value)之间的映射,5中不同类型的值分别为字符串(string),列表(list),散列(hash),集合(set)和有序集合(sorted set ...
- Redis 常用数据结构及其控制命令整合
Redis 键值支持5种基本结构,分别是字符串,列表,哈希,集合,有序集合.每一种数据结构都有对应的取值和设值命令,辅助命令,除此之外,还有一些全局命令,用来管理Redis存储的所有 键. 全局命令 ...
- 使用控制台对Redis执行增删改查命令
使用控制台对Redis执行增删改查命令 在上一篇里,我们已经安装了redis.这一篇我们将一起来学习如何使用"控制台"管理Redis 首先肯定是打开一个控制台,在windows系统 ...
- redis学习-集合set常用命令
redis学习-集合set常用命令 1.sadd:添加一个元素到集合中(集合中的元素无序的并且唯一) 2.smembers:查看集合中所有的元素(上图事例) 3.srem:删除结合中指定的元素 4 ...
- redis学习-散列表常用命令(hash)
redis学习-散列表常用命令(hash) hset,hmset:给指定散列表插入一个或者多个键值对 hget,hmget:获取指定散列表一个或者多个键值对的值 hgetall:获取所欲哦键值以及 ...
- redis事务中的WATCH命令和基于CAS的乐观锁
转自:http://blog.sina.com.cn/s/blog_ae8441630101cgy3.html 在Redis的事务中,WATCH命令可用于提供CAS(check-and-set)功能. ...
- Redis的增删改查命令总结与持久化方式
原文:Redis的增删改查命令总结与持久化方式 Redis是用C语言实现的,一般来说C语言实现的程序"距离"操作系统更近,执行速度相对会更快. Redis使用了单线程架构,预防了多 ...
- Redis bin目录和info命令
1.Redis bin目录和info命令 概述: bin目录是说我们的redis的安装目录中的bin目录,里面存放着一些可执行文件 info命令会列出当前连接的Redis实例的所有指标信息 下面我就对 ...
- Redis 几个类型常用命令
Redis 字符串(String) 下表列出了常用的 redis 字符串命令: 序号 命令及描述1 SET key value 设置指定 key 的值2 GET key 获取指定 key 的值.3 G ...
随机推荐
- C# 基础连接已经关闭: 发送时发生错误
在程序中获取某个https网址的源码,GetRespose()时 出现了“基础连接已经关闭: 发送时发生错误.”的错误提示. 翻了论坛后,有个仁兄说: //.net 4 ...
- Python 简单模块学习
1. openpyxl / xlrd / xlwt => 操作Excel 文件(xlsx格式) => xlrd + xlwt : 只能操作xls文件,分别负责读写, 暂时不讨论 => ...
- pagespeed模块安装——Nginx、Tengine
1.安装好nginx或者tengine 2.下载pagespeed模块并且解压 sudo mkdir -p /usr/local/tengine/modules wget https://github ...
- 【转】ACM各种WA的说明及可能的原因
转载地址:http://blog.csdn.net/qq_15015129/article/details/52738184 1.答案错误 —— wrong answer 就是最常见的.这个没办法,基 ...
- jquery 常用工具方法
inArray(value, array [, fromIndex ])方法类似于原生javascript的indexOf()方法,没有找到匹配元素时它返回-1.如果数组第一个元素匹配参数,那么$.i ...
- Thinkphp 导出大量数据 csv格式
public function test2() { $user_count = M('department')->count(); $page = ceil($user_count / 1000 ...
- JVM指令集(指令码、助记符、功能描述)
JVM指令集(指令码.助记符.功能描述) 指令码 助记符 功能描述 0x00 nop 无操作 0x01 aconst_null 指令格式: aconst_null 功能描述: null进栈. 指令 ...
- Hadoop Shell
1.常用的一些Shell 再好的博客,都不如官方文档好用: http://hadoop.apache.org/docs/r1.0.4/cn/hdfs_shell.html
- JAVA&JS debug
JAVA Chrome Sources 如果当前代码所在文件页面为一界面 → →| -------------------------- ↓↑ ...
- python读写操作csv及excle文件
1.python读写csv文件 import csv #读取csv文件内容方法1 csv_file = csv.reader(open('testdata.csv','r')) next(csv_fi ...