Spring boot整合Redis(入门教程)
目录
- 源码分析
- 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(入门教程)相关推荐
- Spring boot整合Redis实现发布订阅(超详细)
Redis发布订阅 基础知识 相关命令 订阅者/等待接收消息 发布者/发送消息 订阅者/成功接收消息 常用命令汇总 原理 Spring boot整合redis 导入依赖 Redis配置 消息封装类(M ...
- Spring Boot基础学习笔记08:Spring Boot整合Redis
文章目录 零.学习目标 1.熟悉Redis相关概念 2.掌握使用Spring Boot整合Redis 一.Redis概述 1.Redis简介 2.Redis优点 (1)存取速度快 (2)数据类型丰富 ...
- Spring Boot整合Shiro + JSP教程(用户认证,权限管理,图片验证码)
在此首先感谢**编程不良人**up主提供的视频教程 代码都是跟着up的视频敲的,遇到的一些问题也是通过CSDN博主提供的教程解决的,在此也感谢那些提供bug解决方案的前辈们~ 项目完整代码已经发布到g ...
- Spring boot - 整合 Redis缓存(上)
一.配置Pom文件 在使用spring boot 2.0整合redis时遇到了好多问题,网上很多例子都是1.x版本的.故2.0没有折腾好所以将2.0降到了1.5.降级后由于thymeleaf版本也会从 ...
- 十一、Spring Boot整合Redis(一)
Spring Boot整合Redis 1. SpringBoot+单例Redis 1)引入依赖 <dependency> <groupId>org.springf ...
- 大聪明教你学Java | Spring Boot 整合 Redis 实现访问量统计
前言 之前开发系统的时候客户提到了一个需求:需要统计某些页面的访问量,记得当时还纠结了一阵子,不知道怎么去实现这个功能,后来还是在大佬的带领下借助 Redis 实现了这个功能.今天又回想起了这件事,正 ...
- Spring Boot 整合Redis 包含Java操作Redis哨兵 作者:哇塞大嘴好帥(哇塞大嘴好帅)
Spring Boot 整合Redis 包含Java操作Redis哨兵 作者:哇塞大嘴好帥(哇塞大嘴好帅) 1. 配置环境 在SpringBoot2.0版本以后,原来使用的jedis被替换成为了let ...
- 微服务Spring Boot 整合 Redis 实现 好友关注
文章目录 ⛅引言 一.Redis 实现好友关注 -- 关注与取消关注 二.Redis 实现好友关注 -- 共同关注功能 ⛵小结 ⛅引言 本博文参考 黑马 程序员B站 Redis课程系列 在点评项目中, ...
- 猿创征文 | 微服务 Spring Boot 整合Redis 实战开发解决高并发数据缓存
文章目录 一.什么是 缓存? ⛅为什么用缓存? ⚡如何使用缓存 二.实现一个商家缓存 ⌛环境搭建 ♨️核心源码 ✅测试接口 三.采用 微服务 Spring Boot 注解开启缓存 ✂️@CacheEn ...
最新文章
- 上周热点回顾(9.7-9.13)
- html php滚动代码,html中滚动条的代码是什么?如何设置html滚动条?
- word List 22
- JQuery------Select标签的各种使用方法
- IDEA工作常用第三方插件
- 作为面试官,最近面试 Java 后端的感受!
- mac 发现 添加 连接 局域网内打印机
- 讲座记录《捷联惯导解算的历史及发展》
- 联想昭阳E46A不能上网
- linux卸载windows boot,windows和Linux双系统卸载Linux系统
- Linux编程,vim/vi环境
- 想不到吧,实体类能自己CRUD,MyBatis-Plus AR模式了解下
- python找零_用python实现零钱找零的三种方法
- mysql查询使用qq邮箱注册_Spring Boot实现qq邮箱验证码注册和登录验证功能
- Java中类对象为空是什么意思?
- 《30天自制操作系统》从入门到放弃
- 代码格式化工具Prettier
- 数据结构(线性表树图)
- 苹果电脑全系换上自研芯片,除了不能打电话,比iPhone 12亮眼多了
- 基于HTML+CSS实现的静态的电影网站【100010106】