likes
comments
collection
share

SpringCache + SpringBoot + Mybatis + Redis实现缓存(案例解析)

作者站长头像
站长
· 阅读数 34

大家好,我是卷心菜。本篇主要讲解用Redis实现缓存,如果您看完文章有所收获,可以三连支持博主哦~,嘻嘻。


一、前言

  • 各位小伙伴们,博主写的Redis专栏有一段时间了,前面讲解了Redis的例如五种常用数据类型、redis实现持久化、主从复制、哨兵模式等等理论知识。接下来,就要开始着重讲解用redis实现各种业务的代码分析和模拟,一起学习吧!

二、pom文件

下面主要介绍重点的依赖:

 		<!--redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--spring cache-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <!--spring cache连接池依赖包-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.6.2</version>
        </dependency>

三、配置文件

# mybatis配置
mybatis.mapper-locations=classpath*:com/agan/redis/mapper/xml/*.xml
# 数据库配置
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springboot_redis?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=1234
# 日志配置
logging.level.com.agan=debug
# swagger2配置
spring.swagger2.enabled=true
# cache配置
spring.redis.database=0
spring.redis.host=12.68.5.13
spring.redis.port=6379  
spring.redis.password=123456
# 连接池最大连接次数,使用负数表示没有限制
spring.redis.lettuce.pool.max-active=8  
# 连接池最大阻塞等待时间
spring.redis.lettuce.pool.max-wait=-1ms
# 连接池最大空闲连接
spring.redis.lettuce.pool.max-idle=8  
# 连接池最小空闲连接
spring.redis.lettuce.pool.min-idle=0  
# 连接超时时间(毫秒)
spring.redis.timeout=5000ms

四、配置类

@Configuration
@EnableCaching
public class RedisConfig {
    @Primary
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
        redisCacheConfiguration = redisCacheConfiguration
                //设置缓存的默认超时时间:30分钟
                .entryTtl(Duration.ofMinutes(30L))
                //如果是空值,不缓存
                .disableCachingNullValues()
                //设置key序列化器
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))
                //设置value序列化器
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()));
        return RedisCacheManager
                .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
                .cacheDefaults(redisCacheConfiguration)
                .build();
    }
    /**
     * key序列化器
     */
    private RedisSerializer<String> keySerializer() {
        return new StringRedisSerializer();
    }
    /**
     * value序列化器
     */
    private RedisSerializer<Object> valueSerializer() {
        return new GenericJackson2JsonRedisSerializer();
    }
}
  • @EnableCaching:注解会触发一个后处理器(post processor ),它检查每个Spring bean是否存在公共方法(public method)上的缓存注释。 如果找到这样的注释,则自动创建代理以拦截方法调用并相应地处理缓存行为。
  • @Primary:同种类型的bean时,有该注解的bean具有最优先性

五、核心代码

@Service
@CacheConfig(cacheNames = { "user" })
public class UserService {
    private static final Logger LOGGER = LoggerFactory.getLogger(UserService.class);
    @Autowired
    private UserMapper userMapper;
    @Cacheable(key="#id")
    public User findUserById(Integer id){
        return this.userMapper.selectByPrimaryKey(id);
    }
    @CachePut(key = "#obj.id")
    public User updateUser(User obj){
        this.userMapper.updateByPrimaryKeySelective(obj);
        return this.userMapper.selectByPrimaryKey(obj.getId());
    }
    @CacheEvict(key = "#id")
    public void deleteUser(Integer id){
        User user=new User();
        user.setId(id);
        user.setDeleted((byte)1);
        this.userMapper.updateByPrimaryKeySelective(user);
    }
}
  • 与用上一篇文章相比,可以发现,核心代码量明显减少了很多,这就是SpringCache的强大之处,接下来剖析剖析核心代码里面的注解。

六、剖析SpringCache注解

  • @CacheConfig:是类级别的注解,统一类的所有缓存key前缀;@CacheConfig(cacheNames = { "user" })代表了该类的所有缓存key值都是"user::"为前缀。

  • @Cacheable(key="#id"):方法级别的注解,可以将运行结果缓存,以后查询相同的数据,直接从缓存中取,不需要调用方法;id的值作为key。

SpringCache + SpringBoot + Mybatis + Redis实现缓存(案例解析) 以上方法被调用时,先从缓存中读取数据,如果缓存没有找到数据,再执行方法体,最后把返回值添加到缓存中。 调用方法传入id=100,那redis对应的key=user::100 ,value通过采用GenericJackson2JsonRedisSerializer序列化为json

  • @CachePut(key = "#obj.id"):方法级别的注解,用于更新缓存。

SpringCache + SpringBoot + Mybatis + Redis实现缓存(案例解析) 以上方法被调用时,先执行方法体,然后springcache通过返回值更新缓存,即key = "#obj.id",value=User

  • @CacheEvict(key = "#id"):方法级别的注解,用于删除缓存。

SpringCache + SpringBoot + Mybatis + Redis实现缓存(案例解析) 以上方法被调用时,先执行方法体,在通过方法参数删除缓存

七、SpringCache的"坑"

  • 对于redis的缓存,SpringCache只支持String,其他的Hash 、List、Set、ZSet都不支持,所以对于Hash 、List、set、ZSet只能用RedisTemplate。

  • 对于多表查询的数据缓存,SpringCache是不支持的,只支持单表的简单缓存。对于多表的整体缓存,只能用RedisTemplate。


感谢阅读,一起进步,嘻嘻~

转载自:https://juejin.cn/post/7133198821428822047
评论
请登录