Spring Boot (24) 使用Spring Cache集成Redis

Posted 海盗屋

tags:

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

Spring 3.1引入了基于注解(annotation)的缓存(cache)技术,它本质不是一个具体的缓存实现方案,而是一个对缓存使用的抽象,通过在既有代码中添加少量它定义的个助攻annotation,就能够达到缓存方法的返回对象的效果。

 

特点

  具备相当好的灵活性,不仅能够使用SpEL来定义缓存的key和各种condition,还提供开箱即用的缓存临时存储方案,也支持和主流的专业缓存例如EHCache、Redis、Guava的集成。

    基于annotation即可使得现有代码支持缓存

    开箱即用Out-Of-The-Box,不用安装和部署额外第三方组件即可使用缓存

    支持Spring Express Language,能使用对象的任何属性或者方法来定义缓存的key和condition

    支持AspectJ,并通过其实现任何方法的缓存支持

    支持自定义key和自定义缓存管理者,具有相当的灵活性和扩展性

 

使用前后

  使用前:

    我们需要硬编码,如果切换Cache Client还需要修改代码,耦合度高,不易于维护

public String get(String key) {
    String value = userMapper.selectById(key);
    if (value != null) {
        cache.put(key,value);
    }
    return value;
}

  使用后:

    基于Spring Cache注解,缓存由开发者自己配置,但不用参与到具体编码

@Cacheable(value = "user", key = "#key")
public String get(String key) {
    return userMapper.selectById(key);
}

 

添加依赖

需要添加redis的依赖 同上篇

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

 

属性配置

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/david2018_db?characterEncoding=utf8
    username: root
    password: 1234
  redis:
    host: 10.211.55.5 #redis服务器地址
    timeout: 10000 #超时时间
    database: 0 #0-15 16个库 默认0
    lettuce:
      pool:
        max-active: 8 #最大连接数
        max-wait: -1 #默认-1 最大连接阻塞等待时间
        max-idle: 8 #最大空闲连接 默认8
        min-idle: 0 #最小空闲连接
  cache:
    type: redis

spring.cache.type 一般来说是根据依赖的包自行装配,但先后顺序会对redis使用有影响,(Jcache->EhCache->Redis->Guava) 最好还是手动配置一下

 

实体类

public class t_user implements Serializable {
    private Integer id;
    private String username;
    private String password;

    ...
}

mybatisDao

@Mapper
public interface tUserDao {
    @Delete("delete from t_user where id = #{id}")
    int delete(int id);

    @Update("update t_user set username = #{username},password = #{password} where id = #{id}")
    int update(t_user user);

    @Select("select * from t_user where id = #{id}")
    t_user getById(int id);
}

Service

@Service
public class t_userService {

    @Resource
    private tUserDao dao;

    @Cacheable(value="t_user",key="#id")
    public t_user getById(int id) {
        System.out.println("进入查询方法");
        return dao.getById(id);
    }

    @CacheEvict(value="t_user",key="#id")
    public int delete(Integer id){
        System.out.println("进入删除方法");
        return dao.delete(id);
    }

    @CachePut(value="t_user",key="#user.id")
    public int update(t_user user) {
        System.out.println("进入修改方法");
        return dao.update(user);
    }
}

Controller

@RequestMapping("/t_user")
@RestController
public class t_userController {
    @Autowired
    private t_userService service;



    @GetMapping("/delete")
    public String delete(int id){
        service.delete(id);
        return "delete";
    }

    @GetMapping("/update")
    public String update(t_user user){
        service.update(user);
        return "update";
    }

    @GetMapping("/getById")
    public String getById(int id){
        return service.getById(id).toString();
    }
}

最后在启动类中使用@EnableCaching启动Cache 

@EnableCaching
@SpringBootApplication
public class BootApplication{

    public static void main(String[] args) {
        SpringApplication.run(BootApplication.class,args);
    }
}

运行测试:http://localhost:8088/t_user/getById?id=1 输入此路径后 控制台只打印一次进入查询方法 说明缓存了 ,而修改 删除是回打印 修改了方法 和删除了的方法的,从而切面去删掉redis中缓存的数据。其中#代表是一个SpEL表达式。

 

根据条件操作缓存

  根据条件操作好uancun内容并不影响数据库操作,条件表达式返回一个布尔值,true/false,当条件为true,则进行缓存操作,否则直接调用方法返回结果。

    长度:@CachePut(value="user",key="#user.id",condition="#user.username.legnth() < 10") 只缓存用户名长度小于10的数据

    大小:@Cacheable(value="user",key="#id",condition="#id < 10") 只缓存id小于10的数据

    组合:@Cacheable(value="user",key="#user.username.concat(#user.password)")

    提前操作:@CacheEvict(value="user",allEntries=true,beforeInvocation=true)加上beforeInvocation=true后,不管内部是否报错,缓存都将被清除,默认情况为false。

 

注解介绍

  @Cacheable(根据方法的请求参数对其结果进行缓存)

    key:缓存的key,可以为空,如果指定要按照SpEL表达式编写,如果不指定,则缺省按照方法的所有参数进行组合(如:@Cacheable(value="user",key="#username"))

    value:缓存的名称,在Spring 配置文件中定义,必须指定至少一个(如:@Cacheable(value="user")或者@Cacheable(value={"user1","user2"})

    condition:缓存的条件,可以为空,使用SpEL编写,返回true或者false,只有为true才进行缓存(如:@Cacheable(value="user",key="#id",condition="#id < 10"))

  @CachePut(根据方法的请求参数对其结果进行缓存,和@Cacheable不同的是,它每次都会触发真实方法的调用)

  @CacheEvict(根据条件对缓存进行清空)

    allEntries:是否清空所有缓存内容,缺省为false,如果指定为true,则方法调用后将立即清空所有缓存(如:@CacheEvict(value="user",key="#id",allEntries=true))

    beforeInvocation:是否在方法执行前就清空,缺省为false,如果指定为true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法抛出异常,则不会清空缓存(如:@CacheEvict(value="user",key="#id",beforeInvocation))

 

以上是关于Spring Boot (24) 使用Spring Cache集成Redis的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot学习总结(24)——Spring Boot 2.5 新特性一览

Spring Boot学习总结(24)——Spring Boot 2.5 新特性一览

曹工说Spring Boot源码(24)-- Spring注解扫描的瑞士军刀,asm技术实战(上)

Spring-boot 2.0.0 M1 - 执行器不工作

Spring Boot教程第24篇:整合docker

Spring boot Artemis 嵌入式代理行为