【SpringBoot2.0系列07】SpringBoot之redis使用(Lettuce版本)
前言
前面三节我们讲解了springboot
与关系型数据库交互,现在我们需要了解一下springboot
,今天我们就需要学习了与nosql
数据库交互,今天我们主要讲一下springboot
如果操作redis
。 目前java操作redis的客户端有jedis
跟Lettuce
。在springboot1.x
系列中,其中使用的是jedis
,但是到了springboot2.x
其中使用的是Lettuce
。 因为我们的版本是springboot2.x
系列,所以今天使用的是Lettuce
。
关于jedis
跟lettuce
的区别:
Lettuce 和 Jedis 的定位都是Redis的client,所以他们当然可以直接连接redis server。
Jedis在实现上是直接连接的redis server,如果在多线程环境下是非线程安全的,这个时候只有使用连接池,为每个Jedis实例增加物理连接
Lettuce的连接是基于Netty的,连接实例(StatefulRedisConnection)可以在多个线程间并发访问,应为StatefulRedisConnection是线程安全的,所以一个连接实例(StatefulRedisConnection)就可以满足多线程环境下的并发访问,当然这个也是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。
实现
1、依赖
新建一个springboot工程,添加如下依赖。
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- redis依赖commons-pool 这个依赖一定要添加 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> </dependencies>
然后在application.yml
配置一下redis
服务器的地址
server: port: 8989 spring: redis: host: 127.0.0.1 port: 6379 # 密码 没有则可以不填 password: 123456 # 如果使用的jedis 则将lettuce改成jedis即可 lettuce: pool: # 最大活跃链接数 默认8 max-active: 8 # 最大空闲连接数 默认8 max-idle: 8 # 最小空闲连接数 默认0 min-idle: 0
2、 redis配置
接下来我们需要配置redis的key跟value的序列化方式,默认使用的JdkSerializationRedisSerializer
这样的会导致我们通过redis desktop manager
显示的我们key跟value的时候显示不是正常字符。 所以我们需要手动配置一下序列化方式 新建一个config
包,在其下新建一个RedisConfig.java
具体代码如下
/** * @Auther: yukong * @Date: 2018/8/17 14:58 * @Description: redis配置 */@Configuration@AutoConfigureAfter(RedisAutoConfiguration.class)public class RedisConfig { /** * 配置自定义redisTemplate * @return */ @Bean RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值 Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper mapper = new ObjectMapper(); mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); serializer.setObjectMapper(mapper); template.setValueSerializer(serializer); //使用StringRedisSerializer来序列化和反序列化redis的key值 template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); template.setHashValueSerializer(serializer); template.afterPropertiesSet(); return template; } }
其中@Configuration
代表这个类是一个配置类,然后@AutoConfigureAfter(RedisAutoConfiguration.class)
是让我们这个配置类在内置的配置类之后在配置,这样就保证我们的配置类生效,并且不会被覆盖配置。其中需要注意的就是方法名一定要叫redisTemplate
因为@Bean
注解是根据方法名配置这个bean的name的。
3、测试
我们需要测试在redis缓存对象的用例,所以我们需要新建一个实体类。
代码如下:
public class User implements Serializable { private static final long serialVersionUID = 1222221L; private Long id; /** * 用户名 */ private String username; /** * 密码 */ private String password; /** * 年龄 */ private Integer age; /** * 性别 1=男 2=女 其他=保密 */ private Integer sex; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Integer getSex() { return sex; } public void setSex(Integer sex) { this.sex = sex; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", age=" + age + ", sex=" + sex + '}'; } } 我们在`Chapter6Application.java`测试一下
代码如下
@RunWith(SpringRunner.class)@SpringBootTestpublic class Chapter6ApplicationTests { @Autowired private RedisTemplate redisTemplate; @Test public void redisTest() { // redis存储数据 String key = "name"; redisTemplate.opsForValue().set(key, "yukong"); // 获取数据 String value = (String) redisTemplate.opsForValue().get(key); System.out.println("获取缓存中key为" + key + "的值为:" + value); User user = new User(); user.setUsername("yukong"); user.setSex(18); user.setId(1L); String userKey = "yukong"; redisTemplate.opsForValue().set(userKey, user); User newUser = (User) redisTemplate.opsForValue().get(userKey); System.out.println("获取缓存中key为" + userKey + "的值为:" + newUser); } }
首先我们引入springboot
的测试环境,然后注入一个RedisTemplate
对象,这里我解释一下为什么我前面让大家在配置redis
的时候 放回RedisTemplate的方法的方法名一定要叫redisTemplate
因为
如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据
如果查询的结果不止一个,那么@Autowired会根据名称来查找。
如果查询的结果为空,那么会抛出异常。解决方法时,使用required=false
如果我们没有把哪个bean命名为redisTemplate
而这里又这么注入,会导致我们使用的springboot
内置的tempalte而不是我们配置的,导致我们的配置不生效,从而埋坑,所以最好的方法就是把方法命名为redisTemplate
从而覆盖系统内置的。
接下来我们运行测试类。结果如下。
image.png
同时查看redis中缓存的结果。
image.png
image.png
作者:余空啊
链接:https://www.jianshu.com/p/feef1421ab0b
共同学习,写下你的评论
评论加载中...
作者其他优质文章