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“)://我们要在目标字符串中找 ...
随机推荐
- 使用pycharm打开sqlite的问题
目录 问题:有同学在sqlite数据库文件执行数据库迁移完成前,点开了他,导致sqlite数据库被pycharm当成文本文件打开了,并且不会改了. 其实sqlite文件和电脑中的其他文件(xx.mp4 ...
- ThreadLocal 超强图解,这次终于懂了~
本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 前言 大家好,我是小彭. 在前面的文章里,我们聊到了散列表的开放寻址法和分离链表法,也聊到了 HashMap ...
- KingbaseES在线wal日志
KingbaseES数据库日志文件记录数据库的历史操作信息, 包含恢复数据库中的所有事务所需的信息. KingbaseES在线WAL日志: WAL日志: 预写式日志(Write-Ahead Loggi ...
- 看完这篇你不能再说不懂SSO原理了!
这一篇是原理篇,接下来还会有一篇实战篇,实战的相关代码是非常火的一个开源项目叫:xxl-sso 一.简介 单点登录(Single Sign On),简称为 SSO. 它的解释是在多个应用系统中,用户只 ...
- Hangfire .NET任务调度框架实例
1.介绍 Hangfire是一个开源的.NET任务调度框架,提供了内置集成化的控制台(后台任务调度面板),可以直观明了的查看作业调度情况. 2.Nuget安装 3.编写代码 1)测试服务:FirstS ...
- GoLang 的协程调度和 GMP 模型
GoLang 的协程调度和 GMP 模型 GoLang 是怎么启动的 关于 GoLang 的汇编语言,请查阅 参考文献[1] 和 参考文献[2] 编写一个简单的 GoLang 程序 main.go, ...
- FCoE简单介绍
目录 FCoE 使用前提 FCoE FCoE是一种融合网络技术,其目的是将FC帧封装到以太网帧中,实现以太网链路与光纤链路通信的功能. SAN一般指存储区域网络,FC SAN 有光纤组网,IP SAN ...
- Postman操作指南
基本使用 基本使用在这里不做记录,大多数人下载完就会用.这里记一下重点. 抓包浏览器 浏览器安装插件postman interceptor:插件在postman-interceptor界面最下面提示的 ...
- Centos7部署rsync配合inotify进行系统文件实时备份
转载csdn: Centos7部署rsync配合inotify进行系统文件实时备份_xixixilalalahaha的博客-CSDN博客
- CSS 子代选择器(>)
后代选择器 后代选择器?是一种多个用空格分隔的选择器,别称包含选择器.范围是当前节点的所有子节点,包括其直接子节点. div#app下的所有 div 元素都使用下面的样式: div#app div { ...