Redis是现在最流行的nosql(非关系型数据库)了,因为它是在内存上操作,所以速度快,非常受大家青睐,今天讲讲如何在SpringBoot里整合Redis。
首先确认自己电脑上有Redis,是不是能见到这个东西呢
如果能用redis的可视化工具RedisDesktopManager查看一下就更稳妥不过,关于RedisDesktopManager的安装和使用可以看我这篇文章。
1、Redis在实际应用面很广,可以做缓存、消息队列等。
2、目前流行的Redis集成到Java环境有两种方案,分别是Jedis和lettuce。老版本中Jedis用的比较多,但是在SpringBoot2.x后官方已经推荐默认lettuce连接了。原因主要是,Jedis虽然线程安全,但占用资源较大,而lettuce基于netty和nio相关实现,性能不但强,而且占用资源更少。
3、我们知道Redis有16个分区(表),如果不配置默认用0号库(第一个)。
4、Redis的默认五个基本类型:String、set、hash、zset(有序集合)、list
5、Spring中的的Redis数据封装有StringRedisTemplate和RedisTemplate
RedisTemplate和StringRedisTemplate的区别:
两者的关系是StringRedisTemplate继承RedisTemplate。
两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。
SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。
StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。(JdkSerializationRedisSerializer)
RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。(StringRedisSerializer)
6、如果Redis要操作对象,pojo一定要序列化(Serializer)。否则不能和Redis交互。
创建一个新的SpringBoot项目
创建时选择Redis依赖,或者创建后导入
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>添加缓存池依赖(如果不配置连接池大小、连接数等可不添加)
<dependency> <groupId>org.apache.commons</groupId> <artifactId> commons-pool2</artifactId> </dependency>application.properties
#SpringBoot所有的配置类,都有一个自动配置类 RedisAutoConfiguration #自动配置类会绑定一个properties配置文件 RedisProperties #配置Redis spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.password= #密码没有就不写 spring.redis.timeout=10000 #设置超时 spring.cache.type=redis #将redis设置为缓存 # Redis默认情况下有16个分片,这里配置具体使用的分片,默认是0 spring.redis.database=1 # 连接池最大连接数(使用负值表示没有限制) 默认 8 spring.redis.lettuce.pool.max-active=8 # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1 spring.redis.lettuce.pool.max-wait=-1 # 连接池中的最大空闲连接 默认 8 spring.redis.lettuce.pool.max-idle=8 # 连接池中的最小空闲连接 默认 0 spring.redis.lettuce.pool.min-idle=0在SpringBootTest类中
@SpringBootTest class SpringbootRedisTestApplicationTests { @Autowired RedisTemplate redisTemplate; @Test void contextLoads() { System.out.println(redisTemplate.execute(RedisConnectionCommands::ping)); } }记得启动Redis先啊亲
为什么SpringBoot有我们还要创建?我们看看自带的RedisAutoConfiguration
可以看到SpringBoot帮我们在容器中生成了两个封装对象,一个是RedisTemplate,还有一个是StringRedisTemplate。但是这个RedisTemplate是<Object,Object>的,显然用的不舒服,我们可以自己整个自定义的配置类来配置RedisTemplate。后面我们也可以测试用自带的和我们自定义的区别。
RedisConfiguration.java
@Configuration @AutoConfigureAfter(RedisAutoConfiguration.class) public class RedisConfiguration { @Bean public RedisTemplate<String, Serializable> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) { RedisTemplate<String, Serializable> template = new RedisTemplate<>(); GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); // 设置键(key)的序列化采用StringRedisSerializer。 template.setKeySerializer(new StringRedisSerializer()); // 设置值(value)的序列化采用jackson的序列化。 template.setValueSerializer(jackson2JsonRedisSerializer); template.setHashKeySerializer(new StringRedisSerializer()); template.setHashValueSerializer(jackson2JsonRedisSerializer); template.setConnectionFactory(redisConnectionFactory); return template; } }User.java
package com.feng.springbootredistest.pojo; import java.io.Serializable; /** * <h3>springboot-redis-test</h3> * <p></p> * * @author : Nicer_feng * @date : 2020-10-07 19:23 **/ public class User implements Serializable { private Integer id; private String name; private String pwd; public User(Integer id, String name, String pwd) { this.id = id; this.name = name; this.pwd = pwd; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", pwd='" + pwd + '\'' + '}'; } }在SpringBootTest中测试我们的模板
package com.feng.springbootredistest; import com.feng.springbootredistest.pojo.User; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.connection.RedisConnectionCommands; import org.springframework.data.redis.core.RedisTemplate; @SpringBootTest class SpringbootRedisTestApplicationTests { @Autowired RedisTemplate redisTemplate; @Autowired RedisTemplate redisCacheTemplate; @Test void contextLoads() { System.out.println(redisTemplate.execute(RedisConnectionCommands::ping)); } @Test public void queryUser1(){ Object user = redisCacheTemplate.opsForValue().get("feng"); if(user!=null){ System.out.println((User) user+" 数据在缓存中读到"); }else{ //假装去了数据库 User userFromMysql = new User(1,"feng1","111111"); redisCacheTemplate.opsForValue().set("feng",userFromMysql); System.out.println(userFromMysql+" 从数据库里拿到并存入redis缓存中"); } } @Test public void queryUser0(){ Object user = redisTemplate.opsForValue().get("feng"); if(user!=null){ System.out.println((User) user+" 数据在缓存中读到"); }else{ User userFromMysql = new User(1,"feng0","000000"); redisTemplate.opsForValue().set("feng",userFromMysql); System.out.println(userFromMysql+" 从数据库里拿到并存入redis缓存中"); } } }我们这里写了两个test,一个是我们自己封装的Template,一个是SpringBoot自带的,分别使用,看看有什么不同。
怎么样,看出区别了吧。主要是我们的json字符串传输问题,代码里我也模拟了redis作为缓存的实际业务情况,controller层的业务也不再赘述,讲到这里基本没啥区别。到这里整合基本结束了。
推荐使用RedisDesktopManager可视化工具实时观察redis内的情况
实体类记得序列化
如果不想配置序列化可以直接使用自带的,但是不利于观察!虽然不影响存取
推荐使用自定义RedisTemplate模板