redisTemplate类学习及理解
List<Object> list = masterRedisTemplate.executePipelined((RedisCallback<Long>) connection -> {
StringRedisConnection redisConn = (StringRedisConnection) connection;
Integer expireTime = XXX;
redisConn.expire(XXX);
RedisUtil.addSameScoreTail(XXXX);
return null;
});
redisTemplate简化Redis数据访问代码的Helper类。在给定对象和中的基础二进制数据之间执行自动序列化/反序列化。中心方法是execute,支持实现X接口的Redis访问代码,它提供了RedisConnection处理,使得RedisCallback实现和调用代码都不需要显式关心检索/关闭Redis连接,或处理连接生命周期异常。对于典型的单步动作,有各种方便的方法。一旦配置好,这个类就是线程安全的。这是Redis支持的核心类。
1 public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {
接口 RedisAccessor:,该接口指定了一组基本的Redis操作,由RedisTemplate实现。不经常使用,但对于可扩展性和可测试性来说是一个有用的选项(因为它很容易被模仿或存根)。
2 private boolean enableTransactionSupport = false;
true:开启之后则开启事务;3 private boolean exposeConnection = false;
曝光链接@Override
public List<Object> executePipelined(RedisCallback<?> action, @Nullable RedisSerializer<?> resultSerializer) {return execute((RedisCallback<List<Object>>) connection -> {
首先开通连接
connection.openPipeline();标志连接是否关闭 这里有个问题时下面这个true设置是为什么 后续是不是会改为false,要不导致内存泄漏了。 :::在deserialize这个方法里传的closePipline参数可以把关闭连接传递过去。
boolean pipelinedClosed = false;
try {其次处理传来的action的doInRedis方法。 这个doinredis方法就是本文第一个代码块的代码,即当前方法入参传过来的代码块的内容。
Object result = action.doInRedis(connection);
if (result != null) {
throw new InvalidDataAccessApiUsageException(
"Callback cannot return a non-null value as it gets overwritten by the pipeline");
}
List<Object> closePipeline = connection.closePipeline();
pipelinedClosed = true;最后调用deserializeMixedResults,把返回结果带入到execute去继续执行。 这个是一个反序列化相关的方法。
return deserializeMixedResults(closePipeline, resultSerializer, hashKeySerializer, hashValueSerializer);
} finally {
if (!pipelinedClosed) {
connection.closePipeline();
}
}
});
}
StringRedisConnection redisConn = (StringRedisConnection) connection; 在调用executePipelined前,可以用来操作数据。
这个execute是executePipelined处理的具体实现。
@Nullable
public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) { Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it");
Assert.notNull(action, "Callback object must not be null"); RedisConnectionFactory factory = getRequiredConnectionFactory();
RedisConnection conn = null;
try { if (enableTransactionSupport) {
// only bind resources in case of potential transaction synchronization
conn = RedisConnectionUtils.bindConnection(factory, enableTransactionSupport);
} else {
conn = RedisConnectionUtils.getConnection(factory);
} boolean existingConnection = TransactionSynchronizationManager.hasResource(factory); RedisConnection connToUse = preProcessConnection(conn, existingConnection); boolean pipelineStatus = connToUse.isPipelined();
if (pipeline && !pipelineStatus) {
connToUse.openPipeline();
} RedisConnection connToExpose = (exposeConnection ? connToUse : createRedisConnectionProxy(connToUse));
T result = action.doInRedis(connToExpose);
具体执行的也是本文最上面的代码块里的方法。
// close pipeline
if (pipeline && !pipelineStatus) {
connToUse.closePipeline();
} // TODO: any other connection processing?
return postProcessResult(result, connToUse, existingConnection);
} finally {
RedisConnectionUtils.releaseConnection(conn, factory);
}
}
redisTemplate其他方法
delete
@Override
public Boolean delete(K key) {
key转成序列化的
byte[] rawKey = rawKey(key);
调用execute方法
Long result = execute(connection -> connection.del(rawKey), true);
判断返回值
return result != null && result.intValue() == 1;
}
这个execute也是调用的上面的execute方法,获取到连接之后,执行代码块里的del命令。
expire
加失效时间
@Override
public Boolean expire(K key, final long timeout, final TimeUnit unit) {
序列化
byte[] rawKey = rawKey(key);
计算超时时间
long rawTimeout = TimeoutUtils.toMillis(timeout, unit); return execute(connection -> {
try {
调用
return connection.pExpire(rawKey, rawTimeout);
} catch (Exception e) {
// Driver may not support pExpire or we may be running on Redis 2.4
return connection.expire(rawKey, TimeoutUtils.toSeconds(timeout, unit));
}
}, true);
}
计算好了之后 同样也是通过execute方法,获取连接后执行。
opsForHash
RedisTemplate.opsForHash().put/get/delete等等
HashOperations
@Override
public <HK, HV> HashOperations<K, HK, HV> opsForHash() {
return new DefaultHashOperations<>(this);
} 这个方法实现了hashOperations接口
class DefaultHashOperations<K, HK, HV> extends AbstractOperations<K, Object> implements HashOperations<K, HK, HV> { @SuppressWarnings("unchecked")
DefaultHashOperations(RedisTemplate<K, ?> template) {
super((RedisTemplate<K, Object>) template);
}
}
@Override
public void put(K key, HK hashKey, HV value) { byte[] rawKey = rawKey(key);
byte[] rawHashKey = rawHashKey(hashKey);
byte[] rawHashValue = rawHashValue(value); execute(connection -> {
这里通过execute方法,把这个代码块执行。具体的参数是key ,hashkey,value 的三个序列化之后的参数。
connection.hSet(rawKey, rawHashKey, rawHashValue);
return null;
}, true);
}
OpsForSet()
RedisTemplate.opsForSet().add(key, value); public Long add(K key, V... values) {
序列化
byte[] rawKey = rawKey(key);
values是多组二进制
byte[][] rawValues = rawValues((Object[]) values);
return execute(connection -> connection.sAdd(rawKey, rawValues), true);
}
大致就是相关的用法,不通的数据结构 ,有自己特有的Operations方法,可以具体查看。
redisTemplate类学习及理解的更多相关文章
- C++中 类的构造函数理解(一)
C++中 类的构造函数理解(一) 写在前面 这段时间完成三个方面的事情: 1.继续巩固基础知识(主要是C++ 方面的知识) 2.尝试实现一个iOS的app,通过完成app,学习iOS开发中要用到的知识 ...
- 分布式缓存技术redis学习—— 深入理解Spring Redis的使用
关于spring redis框架的使用,网上的例子很多很多.但是在自己最近一段时间的使用中,发现这些教程都是入门教程,包括很多的使用方法,与spring redis丰富的api大相径庭,真是浪费了这么 ...
- JDK学习---深入理解java中的HashMap、HashSet底层实现
本文参考资料: 1.<大话数据结构> 2.http://www.cnblogs.com/dassmeta/p/5338955.html 3.http://www.cnblogs.com/d ...
- JDK学习---深入理解java中的LinkedList
本文参考资料: 1.<大话数据结构> 2.http://blog.csdn.net/jzhf2012/article/details/8540543 3.http://blog.csdn. ...
- python基础知识的学习和理解
参考链接:https://github.com/yanhualei/about_python/tree/master/python_learning/python_base python基础知识笔 ...
- 【log4j】的学习和理解 + 打印所有 SQL
log4j 1.2 学习和理解 + 打印所有 SQL 一.基本资料 官方文档:http://logging.apache.org/log4j/1.2/manual.html(理解基本概念和其他) lo ...
- 【一】ERNIE:飞桨开源开发套件,入门学习,看看行业顶尖持续学习语义理解框架,如何取得世界多个实战的SOTA效果?
参考文章: 深度剖析知识增强语义表示模型--ERNIE_财神Childe的博客-CSDN博客_ernie模型 ERNIE_ERNIE开源开发套件_飞桨 https://github.com/Pad ...
- 转 关于C#中派生类调用基类构造函数的理解
关于C#中派生类调用基类构造函数的理解 .c#class 本文中的默认构造函数是指在没有编写构造函数的情况下系统默认的无参构造函数 1. 当基类中没有自己编写构造函数时,派生类默认的调用 ...
- 【转】Date类学习总结(Calendar Date 字符串 相互转换 格式化)
原文网址:http://www.blogjava.net/jerry-zhaoj/archive/2008/10/08/233228.html Date类学习总结 1.计算某一月份的最大天数 Cale ...
- (转)regex类(个人理解)
regex类(个人理解) C#regex是正则表达式类用于string的处理,查找匹配的字符串.1,先看一个例子Regex regex=new Regex(@”OK“)://我们要在目标字符串中找 ...
随机推荐
- 动力节点—day04
final关键字 final修饰的类无法被继承 final修饰的方法无法被覆盖 final修饰的变量只能赋一次值 fianl的引用一旦指向某个对象,则不能重新指向其他对象,但该引用指向对象内部的数据是 ...
- Containerd NRI 插件
Github:https://github.com/containerd/nri.git Slide:https://static.sched.com/hosted_files/kccncna2022 ...
- 阿里百秀后台管理项目笔记 ---- Day03
来吧展示: step1:所有文章数据展示 引入 functions.php 文件执行数据库查询以及判断用户登录状态 require_once '../functions.php'; get_useri ...
- 为什么要使用 chmod 777
如上图所示, 不使用sudo,报错没有权限 使用sudo,报错找不到命令 只好chmod 777一下了
- VUE16 检测数据变化的原理
部分转自:https://www.vue-js.com/topic/6129d7d661c8f900316ae37a 1 简介 Vue采用MVVM(数据驱动视图)的模式,去充当MVVM中的VM层,在数 ...
- vscode在UBUNTU下使用CMAKE编译
打开一个含有CMakeLists.txt的文件夹 在.vscode要建立三个json文件才能对Cmake工程进行编译和调试,分别是c_cpp_properties.json,launch.json和t ...
- 2021级《JAVA语言程序设计》上机考试试题3
ok,现在是学生的界面实现,因为代码上篇都给出来了,那个是打分卡里面要求全了的,然后service,servlet不全,嗯,刚刚忘说了,没写完,就写了那么多. 先注册: 代码如下: <%@ pa ...
- 【源码】RapidJSON 源码剖析(0):关于 RapidJSON
RapidJSON 源码剖析(0):关于 RapidJSON 为什么会有<RapidJSON 源码剖析>系列博文? 之前转载的 Technique to Read Source Code ...
- What?JMeter做UI自动化!
JMeter做UI自动化 不推荐,好别扭,但可行 插件安装 搜插件selenium,安装 添加config 添加线程组 右键线程组->添加->配置元件->jp@gc - Chrome ...
- CCRD_TOC_2008年第1期
中信国健临床通讯 2008年第1期 目 录 类风湿关节炎 1 一种新型.实用的RA活动度评估方法:完成评估只需三分钟 Fleischmann RM, Schiff MH, Keystone EC, ...