springboot2.1.7整合redis(二)

一、springboot整合redis,基于springboot的缓存技术

先在这里说明所用的版本号为2.1.7,一定得注意版本的问题,因为springboot1.0与springboot‘2.0整合redis上有很多不同,这里所用的是2.0以上的版本,至于springboot2.0与springboot1.0的redis配置,参照springboot1.5.x版本于springboot2.x版本reids使用的不同
还有,此篇博客是基于上一篇博客的续集,不明此参照上一篇博客springboot的缓存机制

1、首先,引入相关的依赖

<!--加入对redis的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <!--2.0以上默认的连接池为lettuce,在这里采用jedis,所以需要排除lettuce的依赖-->
            <exclusions>
                <exclusion>
                    <groupId>io.lettuce</groupId>
                    <artifactId>lettuce-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--加入redis的jar包,并引用依赖包conmons-pool-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <!--spring2.0集成redis所需common-pool2-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.5.0</version>
            <!--<version>2.4.2</version>-->
        </dependency>

2.x默认的连接池为lettuce,1.5.x默认的连接池为jedis,这里我们排除对lettuce的依赖,加入jedis连接池的jar以及2.x中redis所需的common-pool2的jar

注:一定要重新引入jedis连接池的jar以及commons-pool2的依赖,博主之前没有引入(看的1.x的教程,自己却用2.x的版本)导致自己配置redis的缓存时,出现了方法链接池对象无法注入的情况,所以要特别提醒,一定要看好版本,对应好相关的配置!!!!!,错误截图:
在这里插入图片描述即RedisCoonectionFactory对象无法注入。

2、改掉springboot默认的CacheManager
springboot的注解@EnableCaching默认开启的为SimpleCacheConfiguration缓存,springboot会根据以下去侦测缓存的提供者:
在这里插入图片描述

默认配置的缓存管理器只能有一种实现,若同时配置多个缓存管理器,排序靠前的会优先加载,之后不会生效,也可以通过@Primary注解让其优先级变高。

因此,我们要用redis的缓存管理器,需要自己配置缓存管理器。

3、配置redis的缓存管理器
在application.properties中配置redis连接参数:

#Matser的ip地址
spring.redis.host=47.94.9.215
#端口号
spring.redis.port=6379
#如果有密码
spring.redis.password=
#客户端超时时间单位是毫秒 默认是2000
spring.redis.timeout=10000

#最大空闲数
spring.redis.maxIdle=300  
#连接池的最大数据库连接数。设为0表示无限制,如果是jedis 2.4以后用redis.maxTotal
#redis.maxActive=600
#控制一个pool可分配多少个jedis实例,用来替换上面的redis.maxActive,如果是jedis 2.4以后用该属性
spring.redis.maxTotal=1000  
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
spring.redis.maxWaitMillis=1000  
#连接的最小空闲时间 默认1800000毫秒(30分钟)
spring.redis.minEvictableIdleTimeMillis=300000  
#每次释放连接的最大数目,默认3
spring.redis.numTestsPerEvictionRun=1024  
#逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
spring.redis.timeBetweenEvictionRunsMillis=30000  
#是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
spring.redis.testOnBorrow=true  
#在空闲时检查有效性, 默认false
spring.redis.testWhileIdle=true  

注意:这里的配置也跟1.x版本的不同,需要特别注意!!!

4、完成配置
通过以上的配置,springboot默认的缓存机制将变为redis缓存,使用@Cacheable将会向redis中缓存数据。

原因:引入redis的以来之后会自动配置redis缓存,同时帮我配置了两个对象,RedisTemplate以及StringRedisTemplate,用来操作redis缓存。
在这里插入图片描述

二、使用对象向redis中存入数据。

1、使用StringRedisTemplate类来向redis中存储string-string数据。

 @Autowired
    private StringRedisTemplate stringRedisTemplate;      //注入对象

    @Override
    public void insert(User user) {
        userMapper.insert(user);
    }

    @Override
    public User findUserByID(Integer id) {
        System.out.println("查询了数据库");
        ValueOperations<String, String> stringStringValueOperations = stringRedisTemplate.opsForValue();    //存入
        stringStringValueOperations.set("xuyong","uahdu");         //取的话这里调用get方法,传入key
        return (User) userMapper.findUserByID(id);
    }

执行完之后,可以看到redis的缓存中增加了
在这里插入图片描述

提示:这里使用类来操作redis,此时不用使用@EnableCaching来开启注解,直接使用缓存即可。

当然,也可以hash来存储数据,此时为:

 HashOperations<String, Object, Object> stringObjectObjectHashOperations = stringRedisTemplate.opsForHash();
 stringObjectObjectHashOperations.put("duau","daj","dand");

在这里插入图片描述

  1. 2、StringRedisTemplate的方法对应操作list、set有:
    在这里插入图片描述

这里给出封装了StringRedisTemplate的工具类,只对应操作string-string类型

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * 工具类
 * 
 */
@Service
@Slf4j
public class IRedisService {
    @Autowired
    protected StringRedisTemplate redisTemplate;

    /**
     * 写入redis缓存(不设置expire存活时间)
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, String value){
        boolean result = false;
        try {
            ValueOperations operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            log.error("写入redis缓存失败!错误信息为:" + e.getMessage());
        }
        return result;
    }

    /**
     * 写入redis缓存(设置expire存活时间)
     * @param key
     * @param value
     * @param expire
     * @return
     */
    public boolean set(final String key, String value, Long expire){
        boolean result = false;
        try {
            ValueOperations operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            log.error("写入redis缓存(设置expire存活时间)失败!错误信息为:" + e.getMessage());
        }
        return result;
    }


    /**
     * 读取redis缓存
     * @param key
     * @return
     */
    public Object get(final String key){
        Object result = null;
        try {
            ValueOperations operations = redisTemplate.opsForValue();
            result = operations.get(key);
        } catch (Exception e) {
            log.error("读取redis缓存失败!错误信息为:" + e.getMessage());
        }
        return result;
    }

    /**
     * 判断redis缓存中是否有对应的key
     * @param key
     * @return
     */
    public boolean exists(final String key){
        boolean result = false;
        try {
            result = redisTemplate.hasKey(key);
        } catch (Exception e) {
            log.error("判断redis缓存中是否有对应的key失败!错误信息为:" + e.getMessage());
        }
        return result;
    }

    /**
     * redis根据key删除对应的value
     * @param key
     * @return
     */
    public boolean remove(final String key){
        boolean result = false;
        try {
            if(exists(key)){
                redisTemplate.delete(key);
            }
            result = true;
        } catch (Exception e) {
            log.error("redis根据key删除对应的value失败!错误信息为:" + e.getMessage());
        }
        return result;
    }

    /**
     * redis根据keys批量删除对应的value
     * @param keys
     * @return
     */
    public void remove(final String... keys){
        for(String key : keys){
            remove(key);
        }
    }
}

2、使用RedisTemplate来存取对象
根据源码可以看出,RedisTemplate只能存取object-object类型的数据,因此对其进行重写,由源码可以知道,原来的RedisTemplate只有在容器中不存在redisTemplate的bean时才会注入bean,否则将不会注入。
在这里插入图片描述
自己定义个配置类,继承CachingConfigurerSupport,重新定义redisTemplate,使其存入的对象自动转为json格式。

@Configuration
public class RedisConfiguration extends CachingConfigurerSupport {

/**
*
     * 注入redisTemplate,这里是将原来的<Object,Object>改变为<String,Object>
     *
     * @param
     * @return
*/


    @Bean
    @ConditionalOnMissingBean(name = "redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory jedisConnectionFactory) {
        //用json格式存储
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);    //将这个注释掉将不会缓存对象的类型
        jackson2JsonRedisSerializer.setObjectMapper(om);

        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(jedisConnectionFactory);
        template.setKeySerializer(jackson2JsonRedisSerializer);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashKeySerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

}

此时,对RedisTemplate对象进行操作,向redis添加缓存。

     @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void insert(User user) {
        userMapper.insert(user);
    }

    @Override
    public User findUserByID(Integer id) {
        System.out.println("查询了数据库");
     /*   ValueOperations<String, String> stringStringValueOperations = stringRedisTemplate.opsForValue();
        stringStringValueOperations.set("xuyong","uahdu");
        HashOperations<String, Object, Object> stringObjectObjectHashOperations = stringRedisTemplate.opsForHash();
        stringObjectObjectHashOperations.put("duau","daj","dand");*/
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set("du",userMapper.findUserByID(id));          //取数时使用get,取出来也为json格式:User{id=2, username='jj', password='619861'}
        return (User) userMapper.findUserByID(id);
    }

运行后redis中增加缓存:
在这里插入图片描述

将配置类中的 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);注释掉将不会缓存类型,如下:
在这里插入图片描述
在这里插入图片描述
使用哪一种可以自己选择!!!

对应的其它list、set、hash操作的redisTemplate的方法有如下:
在这里插入图片描述

三、总结

采用redis缓存有两种方法,一种直接使用springboot的缓存机制,使用注解来向redis中缓存数据,另一种直接使用RedisTemplate和StringRedisTemplate这两个类来向redis中缓存数据。不管使用哪种,都要特别注意版本问题,再次提示,1.x和2.x的springboot对于redis缓存配置是不一样的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值