目录

  • 源码分析
  • jedis VS lettuce
  • 整合测试
    • 导入依赖
    • 配置连接
    • 测试
      • 存入字符串
      • 存入对象
      • 五大数据类型操作
    • 自定义RedisConfig
      • 存入对象
    • Redis工具类(常用API)

以下是Redis相关笔记总结,方便自己以后复习,同时也希望对大家有所帮助。

内容 地址链接
Redis在Linux环境下的详细安装教程 https://blog.csdn.net/BBQ__ZXB/article/details/123905061
Redis中五大基本数据类型和三种特殊数据类型 https://blog.csdn.net/BBQ__ZXB/article/details/124169168
Redis中基本事务操作及乐观锁的实现 https://blog.csdn.net/BBQ__ZXB/article/details/124192251
Java中使用JedisAPI操作Redis中五大基本数据类型 https://blog.csdn.net/BBQ__ZXB/article/details/124194220
Spring boot整合Redis(入门教程) https://blog.csdn.net/BBQ__ZXB/article/details/124301234
Redis主从复制详解(入门教程) https://blog.csdn.net/BBQ__ZXB/article/details/124802602
Spring boot整合Redis实现发布订阅(超详细) https://blog.csdn.net/BBQ__ZXB/article/details/124980860
Redis执行save命令时报错ERR https://blog.csdn.net/BBQ__ZXB/article/details/123995289

源码分析

SpringBoot2.x之后,原来使用的jedis被替换为了lettuce

SpringBoot 所有的配置类,都有一个自动配置类 RedisAutoConfiguration
每一个自动配置类都绑定一个properties配置文件 RedisProperties

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {public RedisAutoConfiguration() {}@Bean@ConditionalOnMissingBean(name = {"redisTemplate"} ) //可以自定义一个redisTemplate来替换默认的@ConditionalOnSingleCandidate(RedisConnectionFactory.class)public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {//默认的RedisTemplate没有过多的设置,redis对象都是需要序列化的//两个泛型都是Object,Object的类型,后期使用需要强制转换<String,Object>RedisTemplate<Object, Object> template = new RedisTemplate();template.setConnectionFactory(redisConnectionFactory);return template;}@Bean@ConditionalOnMissingBean//由于String是redis中最常用的类型,所以单独提出来一个bean@ConditionalOnSingleCandidate(RedisConnectionFactory.class)public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {return new StringRedisTemplate(redisConnectionFactory);}
}

redis相关配置可以查看源码中的RedisProperties类,@EnableConfigurationProperties({RedisProperties.class})

注解介绍:

注解 作用
@Configuration 用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法
@EnableConfigurationProperties 使使用 @ConfigurationProperties 注解的类生效
@ConditionalOnMissingBean 判断当前需要注入Spring容器中的bean的实现类是否已经含有,有的话不注入,没有就注入

jedis VS lettuce

jedis:采用直连,多个线程操作的话,是不安全的。如果想要避免不安全的,使用jedis pool连接池!更像BIO模式

lettuce:采用netty,实例可以在多个线程中进行共享,不存在线程不安全的情况,可以减少线程数据,更像NIO模式


整合测试

导入依赖

<!--操作redis-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

配置连接

#配置redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
#spring.redis.database=0  //默认是数据库0

测试

存入字符串

@SpringBootTest
class RedisSpringbootApplicationTests {@Autowiredprivate RedisTemplate redisTemplate;@Testvoid contextLoads() {//获取redis的连接对象RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();connection.flushDb();connection.flushAll();redisTemplate.opsForValue().set("mykey0", "呼呼");System.out.println(redisTemplate.opsForValue().get("mykey0"));}}

在Redis可视化管理软件中显示结果:

存入对象

User类:

@Component
@AllArgsConstructor
@NoArgsConstructor
@Data
//在开发中,所有的pojo类都会序列化
public class User implements Serializable{private String name;private int age;
}

测试程序:

@Testpublic void test(){//真实开发中都使用json来传递对象User user = new User();user.setName("笨笨熊2");user.setAge(4);redisTemplate.opsForValue().set("user",user);System.out.println(redisTemplate.opsForValue().get("user"));}

User类未序列化时运行结果:

使User类 implements Serializable,从而序列化。

序列化后可正常运行,在Redis可视化管理软件中显示结果:

查看源码发现由于Redis默认序列化是方式是JdkSerializationRedisSerializer,因此可读性较差


五大数据类型操作

五种数据类型的API操作和Linux下的指令一样,具体可参照另一篇文章
Redis中五大基本数据类型和三种特殊数据类型详解

操作代码 操作说明
redisTemplate 操作不用数据类型,api和指令一样
opsForValue() 操作字符串
opsForList() 操作List
opsForSet() 操作Set
opsForHash 操作Hash
opsForZSet 操作ZSet

除了基本的操作,常用的方法都可以直接通过redisTemplate操作,比如事务和基本CRUD(增删改查)


自定义RedisConfig

自定义配置类中使用Jackson2JsonRedisSerializer进行序列化

@Configuration
public class RedisConfig {//编写配置类,可模仿RedisAutoConfiguration配置类,该类在开发中可直接使用@Bean@SuppressWarnings("all")//@ConditionalOnSingleCandidate(RedisConnectionFactory.class)public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {//由于源码autoConfig中是<Object, Object>,开发中一般直接使用<String,Object>RedisTemplate<String, Object> template = new RedisTemplate();template.setConnectionFactory(factory);//Json序列化配置Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);//String的序列化StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();//key采用string的序列化template.setKeySerializer(stringRedisSerializer);//hash的key采用string的序列化template.setKeySerializer(stringRedisSerializer);//value序列化采用jacksontemplate.setValueSerializer(jackson2JsonRedisSerializer);//hash的value序列化方式采用jacksontemplate.setValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}
}

存入对象

 @Testpublic void test(){RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();connection.flushAll();//真实开发中都使用json来传递对象User user = new User();for (int i=1;i<=10;i++){user.setName("笨笨熊"+i);user.setAge(i);redisTemplate.opsForValue().set("user"+i,user);}}

Redis可视化工具中:

Redis工具类(常用API)

@Component
public class RedisUtils {//注入自定义redisTemplate@Autowired@Qualifier("redisTemplate")private RedisTemplate redisTemplate;/**========================================================================*//*** 指定缓存失效时间** @param key  键* @param time 时间(秒)* @return boolean**/public boolean expire(String key, long time) {try {if (time > 0) {redisTemplate.expire(key, time, TimeUnit.SECONDS);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 根据key 获取过期时间** @param key 键* @return 时间(秒),返回0表示永久有效**/public long getExpire(String key) {return redisTemplate.getExpire(key, TimeUnit.SECONDS);}/*** 判断key是否存在** @param key 键* @return true 存在 false不存在**/public boolean hasKey(String key) {try {return redisTemplate.hasKey(key);} catch (Exception e) {e.printStackTrace();return false;}}/*** 删除缓存** @param key 键**/public void del(String... key) {if (key != null && key.length > 0) {redisTemplate.delete(key[0]);} else {redisTemplate.delete(CollectionUtils.arrayToList(key));}}/**==========================String===========================================*//*** @param key 键* @return 值* */public Object get(String key){return key ==null?null:redisTemplate.opsForValue().get(key);}/*** 普通缓存存入* @param key 键* @param value 值* @return true 成功 false失败* */public boolean set(String key,Object value){try{redisTemplate.opsForValue().set(key,value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/***普通缓存入并设置时间* @param key 键* @param value 值* @param time 时间(秒),time要大于0,如果time小于等于0,将设置无期限* @return true 成功 false 失败* */public boolean set(String key,Object value,long time){try{if (time>0){redisTemplate.opsForValue().set(key,value,time,TimeUnit.SECONDS);}else{set(key,value);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 递增* @param key 键* @param delta 要增加几(大于0)* */public long incr(String key,long delta){if (delta<0){throw new RuntimeException("递增因子必须大于0");}return redisTemplate.opsForValue().increment(key,delta);}/*** 递减** @param key   键* @param delta 要减少几(小于0)*/public long decr(String key, long delta) {if (delta < 0) {throw new RuntimeException("递减因子必须大于0");}return redisTemplate.opsForValue().increment(key, -delta);}/**==========================Map===========================================*//*** HashGet* @param key 键 不能为null* @param item 项 不能为null* */public Object hget(String key,String item){return redisTemplate.opsForHash().get(key,item);}/*** 获取hashKey对应的所有键值** @param key 键* @return 对应的多个键值*/public Map<Object, Object> hmget(String key) {return redisTemplate.opsForHash().entries(key);}/*** HashSet** @param key 键* @param map 对应多个键值*/public boolean hmset(String key, Map<String, Object> map) {try {redisTemplate.opsForHash().putAll(key, map);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** HashSet 并设置时间** @param key  键* @param map  对应多个键值* @param time 时间(秒)* @return true成功 false失败*/public boolean hmset(String key, Map<String, Object> map, long time) {try {redisTemplate.opsForHash().putAll(key, map);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 向一张hash表中放入数据,如果不存在将创建** @param key   键* @param item  项* @param value 值* @return true 成功 false失败*/public boolean hset(String key, String item, Object value) {try {redisTemplate.opsForHash().put(key, item, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 向一张hash表中放入数据,如果不存在将创建** @param key   键* @param item  项* @param value 值* @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间* @return true 成功 false失败*/public boolean hset(String key, String item, Object value, long time) {try {redisTemplate.opsForHash().put(key, item, value);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 删除hash表中的值** @param key  键 不能为null* @param item 项 可以使多个 不能为null*/public void hdel(String key, Object... item) {redisTemplate.opsForHash().delete(key, item);}/*** 判断hash表中是否有该项的值** @param key  键 不能为null* @param item 项 不能为null* @return true 存在 false不存在*/public boolean hHasKey(String key, String item) {return redisTemplate.opsForHash().hasKey(key, item);}/*** hash递增 如果不存在,就会创建一个 并把新增后的值返回** @param key  键* @param item 项* @param by   要增加几(大于0)*/public double hincr(String key, String item, double by) {return redisTemplate.opsForHash().increment(key, item, by);}/*** hash递减** @param key  键* @param item 项* @param by   要减少记(小于0)*/public double hdecr(String key, String item, double by) {return redisTemplate.opsForHash().increment(key, item, -by);}/**=============================set============================*//*** 根据key获取Set中的所有值** @param key 键*/public Set<Object> sGet(String key) {try {return redisTemplate.opsForSet().members(key);} catch (Exception e) {e.printStackTrace();return null;}}/*** 根据value从一个set中查询,是否存在** @param key   键* @param value 值* @return true 存在 false不存在*/public boolean sHasKey(String key, Object value) {try {return redisTemplate.opsForSet().isMember(key, value);} catch (Exception e) {e.printStackTrace();return false;}}/*** 将数据放入set缓存** @param key    键* @param values 值 可以是多个* @return 成功个数*/public long sSet(String key, Object... values) {try {return redisTemplate.opsForSet().add(key, values);} catch (Exception e) {e.printStackTrace();return 0;}}/*** 将set数据放入缓存** @param key    键* @param time   时间(秒)* @param values 值 可以是多个* @return 成功个数*/public long sSetAndTime(String key, long time, Object... values) {try {Long count = redisTemplate.opsForSet().add(key, values);if (time > 0)expire(key, time);return count;} catch (Exception e) {e.printStackTrace();return 0;}}/*** 获取set缓存的长度** @param key 键*/public long sGetSetSize(String key) {try {return redisTemplate.opsForSet().size(key);} catch (Exception e) {e.printStackTrace();return 0;}}/*** 移除值为value的** @param key    键* @param values 值 可以是多个* @return 移除的个数*/public long setRemove(String key, Object... values) {try {Long count = redisTemplate.opsForSet().remove(key, values);return count;} catch (Exception e) {e.printStackTrace();return 0;}}/** ===============================list=================================*//*** 获取list缓存的内容** @param key   键* @param start 开始* @param end   结束 0 到 -1代表所有值*/public List<Object> lGet(String key, long start, long end) {try {return redisTemplate.opsForList().range(key, start, end);} catch (Exception e) {e.printStackTrace();return null;}}/*** 获取list缓存的长度** @param key 键*/public long lGetListSize(String key) {try {return redisTemplate.opsForList().size(key);} catch (Exception e) {e.printStackTrace();return 0;}}/*** 通过索引 获取list中的值** @param key   键* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推*/public Object lGetIndex(String key, long index) {try {return redisTemplate.opsForList().index(key, index);} catch (Exception e) {e.printStackTrace();return null;}}/*** 将list放入缓存** @param key   键* @param value 值*/public boolean lSet(String key, Object value) {try {redisTemplate.opsForList().rightPush(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 将list放入缓存** @param key   键* @param value 值* @param time  时间(秒)*/public boolean lSet(String key, Object value, long time) {try {redisTemplate.opsForList().rightPush(key, value);if (time > 0)expire(key, time);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 将list放入缓存** @param key   键* @param value 值* @return*/public boolean lSet(String key, List<Object> value) {try {redisTemplate.opsForList().rightPushAll(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 将list放入缓存** @param key   键* @param value 值* @param time  时间(秒)* @return*/public boolean lSet(String key, List<Object> value, long time) {try {redisTemplate.opsForList().rightPushAll(key, value);if (time > 0)expire(key, time);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 根据索引修改list中的某条数据** @param key   键* @param index 索引* @param value 值* @return*/public boolean lUpdateIndex(String key, long index, Object value) {try {redisTemplate.opsForList().set(key, index, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 移除N个值为value** @param key   键* @param count 移除多少个* @param value 值* @return 移除的个数*/public long lRemove(String key, long count, Object value) {try {Long remove = redisTemplate.opsForList().remove(key, count, value);return remove;} catch (Exception e) {e.printStackTrace();return 0;}}
}

Spring boot整合Redis(入门教程)相关推荐

  1. Spring boot整合Redis实现发布订阅(超详细)

    Redis发布订阅 基础知识 相关命令 订阅者/等待接收消息 发布者/发送消息 订阅者/成功接收消息 常用命令汇总 原理 Spring boot整合redis 导入依赖 Redis配置 消息封装类(M ...

  2. Spring Boot基础学习笔记08:Spring Boot整合Redis

    文章目录 零.学习目标 1.熟悉Redis相关概念 2.掌握使用Spring Boot整合Redis 一.Redis概述 1.Redis简介 2.Redis优点 (1)存取速度快 (2)数据类型丰富 ...

  3. Spring Boot整合Shiro + JSP教程(用户认证,权限管理,图片验证码)

    在此首先感谢**编程不良人**up主提供的视频教程 代码都是跟着up的视频敲的,遇到的一些问题也是通过CSDN博主提供的教程解决的,在此也感谢那些提供bug解决方案的前辈们~ 项目完整代码已经发布到g ...

  4. Spring boot - 整合 Redis缓存(上)

    一.配置Pom文件 在使用spring boot 2.0整合redis时遇到了好多问题,网上很多例子都是1.x版本的.故2.0没有折腾好所以将2.0降到了1.5.降级后由于thymeleaf版本也会从 ...

  5. 十一、Spring Boot整合Redis(一)

    Spring Boot整合Redis    1. SpringBoot+单例Redis 1)引入依赖 <dependency>     <groupId>org.springf ...

  6. 大聪明教你学Java | Spring Boot 整合 Redis 实现访问量统计

    前言 之前开发系统的时候客户提到了一个需求:需要统计某些页面的访问量,记得当时还纠结了一阵子,不知道怎么去实现这个功能,后来还是在大佬的带领下借助 Redis 实现了这个功能.今天又回想起了这件事,正 ...

  7. Spring Boot 整合Redis 包含Java操作Redis哨兵 作者:哇塞大嘴好帥(哇塞大嘴好帅)

    Spring Boot 整合Redis 包含Java操作Redis哨兵 作者:哇塞大嘴好帥(哇塞大嘴好帅) 1. 配置环境 在SpringBoot2.0版本以后,原来使用的jedis被替换成为了let ...

  8. 微服务Spring Boot 整合 Redis 实现 好友关注

    文章目录 ⛅引言 一.Redis 实现好友关注 -- 关注与取消关注 二.Redis 实现好友关注 -- 共同关注功能 ⛵小结 ⛅引言 本博文参考 黑马 程序员B站 Redis课程系列 在点评项目中, ...

  9. 猿创征文 | 微服务 Spring Boot 整合Redis 实战开发解决高并发数据缓存

    文章目录 一.什么是 缓存? ⛅为什么用缓存? ⚡如何使用缓存 二.实现一个商家缓存 ⌛环境搭建 ♨️核心源码 ✅测试接口 三.采用 微服务 Spring Boot 注解开启缓存 ✂️@CacheEn ...

最新文章

  1. 上周热点回顾(9.7-9.13)
  2. html php滚动代码,html中滚动条的代码是什么?如何设置html滚动条?
  3. word List 22
  4. JQuery------Select标签的各种使用方法
  5. IDEA工作常用第三方插件
  6. 作为面试官,最近面试 Java 后端的感受!
  7. mac 发现 添加 连接 局域网内打印机
  8. 讲座记录《捷联惯导解算的历史及发展》
  9. 联想昭阳E46A不能上网
  10. linux卸载windows boot,windows和Linux双系统卸载Linux系统
  11. Linux编程,vim/vi环境
  12. 想不到吧,实体类能自己CRUD,MyBatis-Plus AR模式了解下
  13. python找零_用python实现零钱找零的三种方法
  14. mysql查询使用qq邮箱注册_Spring Boot实现qq邮箱验证码注册和登录验证功能
  15. Java中类对象为空是什么意思?
  16. 《30天自制操作系统》从入门到放弃
  17. 代码格式化工具Prettier
  18. 数据结构(线性表树图)
  19. 苹果电脑全系换上自研芯片,除了不能打电话,比iPhone 12亮眼多了
  20. 基于HTML+CSS实现的静态的电影网站【100010106】

热门文章

  1. 编写大并发高负载通讯程序
  2. 【Matlab】求解微分方程{上}(通解和特解)
  3. FCN全卷积网络模型——高分辨率遥感影像地物识别
  4. oracle 基础dbms错误,更改对 DBMS 错误的响应
  5. 手游开发-客户端那些事1
  6. Flash与服务器通信简介
  7. 企业分公司与总部之间的网络连通高效方案
  8. 计算机技能培训心得,计算机技能培训心得感想.doc
  9. 世界 5G 通信频段和运行模式
  10. flink各版本变化和新增特性