SpringBoot2.X整合Redis

Posted CodeLuoJay

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot2.X整合Redis相关的知识,希望对你有一定的参考价值。

前言

Redis作为一个优秀的nosql数据库,能快速读取数据,非常值得我们去学习

SpringBoot也对Redis提供非常友好的整合,那么还等什么,撸起袖子就是干

下载Redis

Redis作为一款开源的软件,下载方式也极为简单,可以从Github下载window版本直接解压

传送门Redis的Github下载网址

传送门Redis中文使用教程

SpringBoot整合Redis过程

工程结构

  1. 通过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创建工程时,是不会自动导入的

  1. 编写实体类

    @Data	//lombok的注解,自动生成setter和getter
    public class User {
        /**
         * 姓名
         */
        private String name;
    
        /**
         * 编号
         */
        private String id;
    
        /**
         * 年龄
         */
        private String age;
    }
    
    
  2. 编写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;
        }
    }
    
  3. 编写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);
        }
    }
    
    
  4. 配置连接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案例效果

  1. 使用PostMan请求RedisController的PostUser方法,会把实体类存进Redis中

  2. 使用PostMan请求RedisController的getUser方法,会把实体类从Redis中取出并返回输出

  3. 使用PostMan请求RedisController的set方法,会把类路径的key和value值存进Redis中

  4. 使用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类型的数据操作
  1. 针对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格式数据直接取出并相应输出

踩坑记录

  1. 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说明设置成功
    
  2. JSON序列化enableDefaultTyping方法过期,过期的方法虽然能用,但作者已经在源码中指明替代的方法

    一些写的比较早的博客都是用这个方法,我在代码中注释掉这个方法并用上替代的方法方便后面的学习的人

  3. Unrecognized token \'CodeLuoJay\': was expecting (JSON String, Number, Array,)

    这是一个Json序列化出错的问题,我遇到的情况是自己萌蠢用了RedisController的set方法把字符串存进redis,结果我用getUser方法取出就报这个错误,因为字符串形式存进去,而要求输出是POJO的实体类对象类型不一致,就会报这个错误

文章配套Github源码:springboot-redis
文章对你有帮助,别忘了start一下给给星星支持一下

以上是关于SpringBoot2.X整合Redis的主要内容,如果未能解决你的问题,请参考以下文章

springboot2.x整合redis

springboot2.x版本整合redis(单机/集群)(使用lettuce)

Springboot2.x整合Redis以及连接哨兵模式/集群模式

Springboot2.x+shiro+redis整合填坑 redis只做缓存的情况

SpringBoot2.x整合Redis缓存自定义序列化

springboot2.x以上整合shiro1.7.1和redis的一些注意事项