1. Redis itself does not provide the msetex command (bulk increase the key and set the expiration time)
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 script (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 script (deleted after acquisition)
* /
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 is not allowed to be empty");
Assert.hasLength (item.getKey (), "Key is not allowed to be empty");
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 ("Execution of redis script exception!", 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. The calling code is as follows
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 ("Return value:" + r);
String key1Val = getdel ("key1");
System.out.println ("Key1 value:" + key1Val);
key1Val = getdel ("key1");
System.out.println ("Key1 value:" + key1Val);
}
3. The returned results are as follows
Return value: 3
The value of key1: value1
value of key1: null
4. The code of sha1 is as follows
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);
// Convert the ciphertext to hexadecimal string form
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 implements msetex and getdel commands