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“)://我们要在目标字符串中找 ...
随机推荐
- Python读取大量Excel文件并跨文件批量计算平均值
本文介绍基于Python语言,实现对多个不同Excel文件进行数据读取与平均值计算的方法. 首先,让我们来看一下具体需求:目前有一个文件夹,其中存放了大量Excel文件:文件名称是每一位同学的 ...
- 论文翻译:2020:ECAPA-TDNN: Emphasized Channel Attention, Propagation and Aggregation in TDNN Based Speaker Verification
论文地址:ECAPA-TDNN:在基于TDNN的说话人验证中强调通道注意.传播和聚集 论文代码:https://github.com/TaoRuijie/ECAPA-TDNN 引用格式:Desplan ...
- 将Grafana嵌入自己的应用
什么是Grafana Grafana是一款强大的可视化工具,无论数据存储在哪里,都可以查询.可视化.警报和理解您的数据.使用Grafana,您可以通过美丽.灵活的仪表板创建.探索和共享所有数据. 场景 ...
- vue学习笔记(一) ---- vue指令(总体大纲)
一.什么是Vue 官方文档:https://cn.vuejs.org/v2/guide/ 关键字: 渐进式框架 自底向上增量开发 视图层 单文件组件 复杂的单页应用 复杂的单页应用: 顾名思义,单页应 ...
- Vue05 初识
1 下载vue.js 进入官网 下载两个版本的vue.js 开发版本和生成版本的区别 开发版本体量更大,包含完整的警告和调试模式 生成版本体量更小,删除了警告 2 打开VSCode 新建一个空文件夹v ...
- UBUNTU18.04安装CUDA
1.官方教程https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#ubuntu-installation 2.在h ...
- Requset02
其他功能: 1. 获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数 1. String getParameter(String name):根据参数名称获取参数值 ...
- 在react项目如何捕获错误
在React项目是如何捕获错误的? 一.是什么 错误在我们日常编写代码是非常常见的 举个例子,在react项目中去编写组件内JavaScript代码错误会导致 React 的内部状态被破坏,导致整个应 ...
- 基于SpringBoot实现操作GaussDB(DWS)的项目实战
摘要:本文就使用springboot结合mybatis plus在项目中实现对GaussDB(DWS)的增删改查操作. 本文分享自华为云社区<基于SpringBoot实现操作GaussDB(DW ...
- Mysql基本使用指南
一. 记录操作 子查询 select * from students where (age, height) = (select max(age), max(height) from students ...