/**
* Copyright (c) 2011-2023, James Zhan 詹波 ([email protected]).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jfinal.plugin.redis;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Function;
import com.jfinal.kit.Func.*;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.redis.serializer.ISerializer;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.params.SetParams;
import redis.clients.jedis.util.SafeEncoder;
/**
* Cache.
* Cache api 添加了中文注释,便于工程师更方便使用,另外还原样保持了
* Jedis api 的方法名称及使用方法,以便于仅仅通过查看 Redis 文档
* 即可快速掌握使用方法
* Redis 命令参考: http://redisdoc.com/
*
* 注意:不要提供 strlen、append、setrange、getrange,经测试这类操作字符串的方法在序列化模式下无法工作
* 因为 String 序列化后的 value 值为会多出来一些额外的字符
*/
public class Cache {
protected String name;
protected JedisPool jedisPool;
protected ISerializer serializer;
protected IKeyNamingPolicy keyNamingPolicy;
protected final ThreadLocal<Jedis> threadLocalJedis = new ThreadLocal<Jedis>();
/**
* 使用 lambda 开放 Jedis API,建议优先使用本方法
* <pre>
* 例子 1:
* Long ret = Redis.use().call(j -> j.incrBy("key", 1));
*
* 例子 2:
* Long ret = Redis.use().call(jedis -> {
* return jedis.incrBy("key", 1);
* });
* </pre>
*/
public <R> R call(Function<Jedis, R> jedis) {
Jedis jd = getJedis();
try {
return jedis.apply(jd);
}
finally {close(jd);}
}
protected Cache() {
}
public Cache(String name, JedisPool jedisPool, ISerializer serializer, IKeyNamingPolicy keyNamingPolicy) {
this.name = name;
this.jedisPool = jedisPool;
this.serializer = serializer;
this.keyNamingPolicy = keyNamingPolicy;
}
/**
* 存放 key value 对到 redis
* 如果 key 已经持有其他值, SET 就覆写旧值,无视类型。
* 对于某个原本带有生存时间(TTL)的键来说, 当 SET 命令成功在这个键上执行时, 这个键原有的 TTL 将被清除。
*/
public String set(Object key, Object value) {
Jedis jedis = getJedis();
try {
return jedis.set(keyToBytes(key), valueToBytes(value));
}
finally {close(jedis);}
}
/**
* setnx 的工作原理与 set 完全相同,唯一的区别是,如果 key 已经存在,则不执行任何操作
* @return 1 表示 key 不存在,0 表示 key 存在
*/
public Long setnx(Object key, Object value) {
Jedis jedis = getJedis();
try {
return jedis.setnx(keyToBytes(key), valueToBytes(value));
}
finally {close(jedis);}
}
/**
* 存放 key value 对到 redis,并将 key 的生存时间设为 seconds (以秒为单位)。
* 如果 key 已经存在, SETEX 命令将覆写旧值。
*/
public String setex(Object key, long seconds, Object value) {
Jedis jedis = getJedis();
try {
return jedis.setex(keyToBytes(key), seconds, valueToBytes(value));
}
finally {close(jedis);}
}
/**
* psetex 与 setex 功能相同,但是生存时间为 milliseconds (以毫秒为单位)。
*/
public String psetex(Object key, long milliseconds, Object value) {
Jedis jedis = getJedis();
try {
return jedis.psetex(keyToBytes(key), milliseconds, valueToBytes(value));
}
finally {close(jedis);}
}
/**
* 返回 key 所关联的 value 值
* 如果 key 不存在那么返回特殊值 nil 。
*/
@SuppressWarnings("unchecked")
public <T> T get(Object key) {
Jedis jedis = getJedis();
try {
return (T)valueFromBytes(jedis.get(keyToBytes(key)));
}
finally {close(jedis);}
}
/**
* 删除给定的一个 key
* 不存在的 key 会被忽略。
*/
public Long del(Object key) {
Jedis jedis = getJedis();
try {
return jedis.del(keyToBytes(key));
}
finally {close(jedis);}
}
/**
* 删除给定的多个 key
* 不存在的 key 会被忽略。
*/
public Long del(Object... keys) {
Jedis jedis = getJedis();
try {
return jedis.del(keysToBytesArray(keys));
}
finally {close(jedis);}
}
/**
* 查找所有符合给定模式 pattern 的 key 。
* KEYS * 匹配数据库中所有 key 。
* KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
* KEYS h*llo 匹配 hllo 和 heeeeello 等。
* KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo 。
* 特殊符号用 \ 隔开
*/
public Set<String> keys(String pattern) {
Jedis jedis = getJedis();
try {
return jedis.keys(pattern);
}
finally {close(jedis);}
}
/**
* 同时设置一个或多个 key-value 对。
* 如果某个给定 key 已经存在,那么 MSET 会用新值覆盖原来的旧值,如果这不是你所希望的效果,请考虑使用 MSETNX 命令:它只会在所有给定 key 都不存在的情况下进行设置操作。
* MSET 是一个原子性(atomic)操作,所有给定 key 都会在同一时间内被设置,某些给定 key 被更新而另一些给定 key 没有改变的情况,不可能发生。
* <pre>
* 例子:
* Cache cache = RedisKit.use(); // 使用 Redis 的 cache
* cache.mset("k1", "v1", "k2", "v2"); // 放入多个 key value 键值对
* List list = cache.mget("k1", "k2"); // 利用多个键值得到上面代码放入的值
* </pre>
*/
public String mset(Object... keysValues) {
if (keysValues.length % 2 != 0)
throw new IllegalArgumentException("wrong number of arguments for mset, keysValues length can not be odd");
Jedis jedis = getJedis();
try {
byte[][] kv = new byte[keysValues.length][];
for (int i=0; i<keysValues.length; i++) {
if (i % 2 == 0)
kv[i] = keyToBytes(keysValues[i]);
else
kv[i] = valueToBytes(keysValues[i]);
}
return jedis.mset(kv);
}
finally {close(jedis);}
}
/**
* 当且仅当所有给定键都不存在时, 为所有给定键设置值。
* 即使只有一个给定键已经存在, MSETNX 命令也会拒绝执行对所有键的设置操作。
* MSETNX 是一个原子性(atomic)操作, 所有给定键要么就全部都被设置, 要么就全部都不设置, 不可能出现第三种状态。
*/
public Long msetnx(Object... keysValues) {
if (keysValues.length % 2 != 0)
throw new IllegalArgumentException("wrong number of arguments for msetnx, keysValues length can not be odd");
Jedis jedis = getJedis();
try {
byte[][] kv = new byte[keysValues.length][];
for (int i=0; i<keysValues.length; i++) {
if (i % 2 == 0)
kv[i] = keyToBytes(keysValues[i]);
else
kv[i] = valueToBytes(keysValues[i]);
}
return jedis.msetnx(kv);
}
finally {close(jedis);}
}
/**
* 返回所有(一个或多个)给定 key 的值。
* 如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。因此,该命令永不失败。
*/
@SuppressWarnings("rawtypes")
public List mget(Object... keys) {
Jedis jedis = getJedis();
t
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论



















收起资源包目录





































































































共 464 条
- 1
- 2
- 3
- 4
- 5
资源评论


wjs2024
- 粉丝: 3400
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- 基于JSP的校园网站的设计与实现论文.doc
- 利用单片机制作简单万年历.doc
- 正确选择财务管理软件[会计实务-会计实操].doc
- 学校开展“2022年网络安全宣传周”活动方案.docx
- 系统集成-大屏监控系统使用说明书.doc
- 普通高中语文教学导向深度学习实践研究方案.doc
- 计算机网络技术模拟试题及答案(最终).doc
- 幼儿园语言文字领导小组网络图.pdf
- 网络防火墙需求分析.doc
- 在Excel中判断单元格是否包含日期【会计实务操作教程】.pptx
- 井下人员定位系统与通信联络系统.ppt
- (源码)基于C++ROS框架的机器人控制系统.zip
- 工程项目管理团队建设.ppt
- 教你如何选择合适的财务软件 .pdf
- 基于单片机的AD转换电路与程序设计.doc
- 网络分析仪E6607C操作指导.ppt
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈



安全验证
文档复制为VIP权益,开通VIP直接复制
