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. servletConfig的应用

    在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数. 当servlet配置了初始化参数后,web容器在创建servlet实例对象 ...

  2. Cannot evaluate the property expression "$([MSBuild]::ValueOrDefault('$(VCTargetsPath)','$(MSBuildExtensionsPath32)\Microsoft.Cpp\v4.0\V140\'))" found at "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuil

    Cannot evaluate the property expression "$([MSBuild]::ValueOrDefault('$(VCTargetsPath)','$(MSBu ...

  3. 用 Inkscape 做 SVG 给 TPath

    FireMonkey 里的 TPathData 支持 SVG 的基本绘图指令,因此可以运用 Inkscape 软件,提取 SVG 的绘图内容,请见图片说明: INKSCAPE https://inks ...

  4. sql 计算地球2个坐标之间的距离

    show variables like '%func%'; set global log_bin_trust_function_creators=1; use scm_wuliudelimiter $ ...

  5. Postgres数据库在Linux中优化

    I/O 优化1 打开 noatime nodirtime,async 方法: 修改 /etc/fstab stat 命令查看 2 调整预读方法: 查看 sudo blockdev --getra /d ...

  6. winfrom 右下角弹窗(渐渐消失)

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  7. dataset数据导出到Excel

    1.将数据写入HTTP输出流/这样子导出以后的数据全在一行中 public void CreateExcel(DataSet ds, string FileName) { HttpResponse r ...

  8. nej+regular环境使用es6的低成本方案

    本文来自 网易云社区 . 希望在生产环境中使用es6/7,babel应该是最普遍的选择.这是babel官网中,它对自己的定义: Babel 自带了一组 ES2015 语法转化器.这些转化器能让你现在就 ...

  9. dataframe初始化

  10. css3箭头

    <!DOCTYPE html> <html lang="en" class="muui-theme-webapp-main"> < ...