SpringBoot2.X整合Redis
前言
Redis作为一个优秀的nosql数据库,能快速读取数据,非常值得我们去学习
SpringBoot也对Redis提供非常友好的整合,那么还等什么,撸起袖子就是干
下载Redis
Redis作为一款开源的软件,下载方式也极为简单,可以从Github下载window版本直接解压
传送门:Redis的Github下载网址
传送门:Redis中文使用教程
SpringBoot整合Redis过程
工程结构
- 通过Maven引入工程依赖
你可以在构建工程的时候分别在NoSQL下勾选Spring Data Redis,Web下勾选SpringWeb,以及Developer Tools下勾选lombok,让IDEA自动为你导入响应的依赖
<!--redis依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!--web依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--apache.commons依赖--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> <!--lombok依赖--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency>
当然也可以直接从我这个贴出的依赖,直接拷贝进pom.xml下,需要特别注意的是commons-pool2这个依赖必须通过手动引入,IDEA创建工程时,是不会自动导入的
编写实体类
@Data //lombok的注解,自动生成setter和getter public class User { /** * 姓名 */ private String name; /** * 编号 */ private String id; /** * 年龄 */ private String age; }
编写Redis配置类
@Configuration // Springboot配置类的注解 public class RedisConfiguration { @Bean // IOC自动转配Bean的注解 public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); // 使用Jackson2JsonRedisSerialize 替换默认序列化 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // enableDefaultTyping方法已过期,在比较老的博客中,踩了坑用activateDefaultTyping替代 // objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance , ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); // 设置value的序列化规则和 key的序列化规则 redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.afterPropertiesSet(); return redisTemplate; } }
编写RedisController类
@RestController public class RedisController { @Autowired private StringRedisTemplate stringRedisTemplate; @Autowired private RedisTemplate redisTemplate; @GetMapping("/get/{key}") public String getRedis(@PathVariable(name="key") String key){ return stringRedisTemplate.opsForValue().get(key); } @PostMapping("/set/{key}/{value}") public String getRedis(@PathVariable(name="key")String key, @PathVariable(name="value")String value){ stringRedisTemplate.opsForValue().set(key,value); return "SUCCESS"; } @PostMapping("/postUser") public String postEntity(){ User user=new User(); user.setId("1"); user.setName("codeluojay"); user.setAge("25"); redisTemplate.opsForValue().set(user.getId(),user); return "SUCCESS"; } @GetMapping("/getUser/{key}") public Object getEntity(@PathVariable(name="key")String key){ return redisTemplate.opsForValue().get(key); } }
配置连接Redis的properties
# Redis数据库索引(默认为0) spring.redis.database=0 # Redis服务器地址 spring.redis.host=localhost # Redis服务器连接端口 spring.redis.port=6379 # Redis服务器连接密码(如果不设置默认为空,那么下面这行代码就不要写上去,否则会报错) #spring.redis.password=root # 连接池最大连接数(使用负值表示没有限制) spring.redis.jedis.pool.max-active=8 # 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.jedis.pool.max-wait=-1 # 连接池中的最大空闲连接 spring.redis.jedis.pool.max-idle=8 # 连接池中的最小空闲连接 spring.redis.jedis.pool.min-idle=0 # 连接超时时间(毫秒) spring.redis.timeout=10000
SpringBoot整合Redis案例效果
使用PostMan请求RedisController的PostUser方法,会把实体类存进Redis中
使用PostMan请求RedisController的getUser方法,会把实体类从Redis中取出并返回输出
使用PostMan请求RedisController的set方法,会把类路径的key和value值存进Redis中
使用PostMan请求RedisController的get方法,会把类路径的key作为key值去获取Redis中对应的value值并返回输出
SpringBoot整合Redis案例知识点
RedisTemplate
1.RedisTemplate 是spring-data-redis针对jedis客户端进行大量封装形成一个便于操作Redis的模板
对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口
方法 | 方法说明 |
---|---|
ValueOperations | 简单K-V操作 |
SetOperations | set类型数据操作 |
ZSetOperations | zset类型数据操作 |
HashOperations | 针对map类型的数据操作 |
ListOperations | 针对list类型的数据操作 |
- 针对Java和redis中的数据“序列化/反序列化”,提供了多种可选择策略(RedisSerializer)
JdkSerializationRedisSerializer:POJO对象的存取场景,使用JDK本身序列化机制,将pojo类通过ObjectInputStream/ObjectOutputStream进行序列化操作,最终redis-server中将存储字节序列。是目前最常用的序列化策略。
StringRedisSerializer:Key或者value为字符串的场景,根据指定的charset对数据的字节序列编码成string,是“new String(bytes, charset)”和“string.getBytes(charset)”的直接封装。是最轻量级和高效的策略。
JacksonJsonRedisSerializer:jackson-json工具提供了javabean与json之间的转换能力,可以将pojo实例序列化成json格式存储在redis中,也可以将json格式的数据转换成pojo实例。因为jackson工具在序列化和反序列化时,需要明确指定Class类型,因此此策略封装起来稍微复杂。【需要jackson-mapper-asl工具支持】
OxmSerializer:提供了将javabean与xml之间的转换能力,目前可用的三方支持包括jaxb,apache-xmlbeans;redis存储的数据将是xml工具。不过使用此策略,编程将会有些难度,而且效率最低;不建议使用。【需要spring-oxm模块的支持】
本文的案例使用到的知识点:
1.使用ValueOperations来进行简单的K-V操作(主要是对String字符串类型的数据进行操作)
2.使用JacksonJsonRedisSerializer对User的JavaBean序列化为json格式存储在redis中和Redis中json格式数据直接取出并相应输出
踩坑记录
redis客户端设置密码和不设密码踩坑
如果你的redis中默认不设置密码,那么在properties中下面的话就不用写上去或者用#注释掉
# Redis服务器连接密码(如果不设置默认为空,那么下面这行代码就不要写上去,否则会报错) # spring.redis.password=root
否则就会报ERR Client sent AUTH, but no password is set 的错误,因为你没设置密码,又要求SpringBoot用密码连接自然会出错
当然不改配置文件
spring.redis.password=root
,还可以通过redis的客户端的命令设置密码防止出现这个错误
# 解决:命令行进入你解压Redis的文件夹找到redis-cli.exe启动这个客户端 F:\Redis-x64-3.2.100 # 查看是否设置了密码: 127.0.0.1:6379> auth root (error) ERR Client sent AUTH, but no password is set # 说明没有设置密码,执行设置密码命令:config set requirepass后面的root就是本次设置的密码 127.0.0.1:6379> config set requirepass root OK # 出现OK说明设置成功
JSON序列化enableDefaultTyping方法过期,过期的方法虽然能用,但作者已经在源码中指明替代的方法
一些写的比较早的博客都是用这个方法,我在代码中注释掉这个方法并用上替代的方法方便后面的学习的人
Unrecognized token ‘CodeLuoJay‘: was expecting (JSON String, Number, Array,)
这是一个Json序列化出错的问题,我遇到的情况是自己萌蠢用了RedisController的set方法把字符串存进redis,结果我用getUser方法取出就报这个错误,因为字符串形式存进去,而要求输出是POJO的实体类对象类型不一致,就会报这个错误