avatar

16.SpringBoot整合之缓存篇(2)

上一篇我们介绍了Spring缓存抽象的概念、原理以及@Cacheable的简单使用。该篇将会一起学习Spring缓存抽象的其他的注解。

一、Spring缓存抽象之@CachePut

  1. @CachePut的作用:首先,@CachePut@Cacheable一样,都是标注在方法上,并且都是会缓存方法的返回值。但唯一不同的是,标注了@CachePut注解的方法,不管是否有缓存,都会执行方法,并且把结果缓存起来。而@Cacheable执行方法前回去检查缓存是否有,如果有就不会执行方法,反之则先执行方法,再把结果缓存起来。
  2. @CachePut的使用场景:可以在更新数据库的某个数据的时候使用。这样既更新了数据库数据,也同步的更新了缓存里面对应的值。
  3. 使用例子:
    1. Controller
    1
    2
    3
    4
    @RequestMapping("/updateUser")
    public User updateUser(User user){
    return userService.updateUser(user);
    }
    1. service
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @Service
    public class UserService {
    @Autowired
    private UserDao userDao;
    //注意:@Cacheable中的key不能使用#result
    @Cacheable(value = "UserCache",key="#id")
    public User getUser(Integer id){
    return userDao.getUser(id);
    }
    //注意:这里的key要和@Cacheable的key值要相同。不然是不会更新缓存中的值。而且返回值也要一样。不然会出现转换异常
    @CachePut(value="UserCache",key="#result.id")
    public User updateUser(User user) {
    return userDao.updateUser(user);
    }
    }
    1. dao
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    @Repository
    public class UserDao {
    private static Map<Integer,User> map = new HashMap<>();
    static{
    map.put(1,new User(1,"张三",18));
    map.put(2,new User(2,"李四",19));
    map.put(3,new User(3,"王五",17));
    map.put(4,new User(4,"赵六",14));
    map.put(5,new User(5,"王小二",20));
    map.put(6,new User(6,"李小四",29));
    map.put(7,new User(7,"赵明",34));
    map.put(8,new User(8,"王柳",16));
    map.put(9,new User(9,"李斯",17));
    map.put(10,new User(10,"孙福",10));
    }

    public User getUser(int id){
    System.out.println("use db select, id is " +id);
    return map.get(id);
    }

    public User updateUser(User user) {
    System.out.println("update User "+ user);
    map.put(user.getId(),user);
    return map.get(user.getId());
    }
    }
    1. 实验结果
      1. 第一次查询,请求地址:http://localhost:8080/user/getUser/1
        1. 控制台打印:use db select, id is 1
        2. 界面响应:{"id": 1,"name": "张三","age": 18}
      2. 请求更新,地址:http://localhost:8080/user/updateUser?id=1&name=张小三&age=20
        1. 控制台打印:update User User{id=1, name='张小三', age=20}
        2. 界面打印:{"id": 1,"name": "张小三","age": 20}
      3. 再次请求查询:http://localhost:8080/user/getUser/1
        1. 控制台打印:此时会走缓存,所以控制台什么也不会打印
        2. 界面显示:{"id": 1,"name": "张小三","age": 20}

二、Spring缓存抽象之@CacheEvict

  1. @CacheEvict作用:缓存清除,也就是清除缓存里面的数据。
  2. 应用场景:数据删除后,同时需要删除缓存中的数据
  3. @CacheEvict注解的参数
    1. allEntries
      1. = true :清除这个缓存的所有数据
      2. = false:只清除对应的缓存数据
    2. beforeInvocation
      1. = false: 缓存的清除是在方法后执行,如果方法出现异常,则不执行缓存清除。
      2. = true:缓存的清除在方法前执行,无论方法调用是否出现异常,都会执行缓存清除。
  4. 使用案例:
    1. controlle
      1
      2
      3
      4
      @RequestMapping("/deleteUser/{id}")
      public User deleteUser(@PathVariable("id") Integer id){
      return userService.deleteUser(id);
      }
    2. service
      1
      2
      3
      4
      @CacheEvict(value="UserCache",key = "#id",allEntries = false)
      public User deleteUser(Integer id) {
      return userDao.deleteUser(id);
      }
    3. dao
      1
      2
      3
      4
      public User deleteUser(Integer id) {
      System.out.println("delete user id is "+ id);
      return map.remove(id);
      }
    4. 实验结果
      1. 第一次查询 请求地址:http://localhost:8080/user/getUser/1
        1. 控制台打印:use db select, id is 1
        2. 界面响应:{"id": 1,"name": "张三","age": 18}
      2. 执行删除请求,请求地址:http://localhost:8080/user/deleteUser/1
        1. 控制台打印:delete user id is 1
        2. 界面响应:{"id": 1,"name": "张三","age": 18}
      3. 再次查询缓存:http://localhost:8080/user/getUser/1
        1. 控制台打印:use db select, id is 1
        2. 界面响应:因为数据已经删除,而且缓存中数据也已经删除。所以结果查出来是空。即,界面没有任何显示

三、Spring缓存抽象之其他注解

  1. @Caching
    • 作用:该注解为CacheableCachePutCacheEvict的组合注解。可以用来定义复杂的缓存规则
  2. @CacheConfig
    • 作用:该注解标注在类上。可以抽取一些公共的信息。比如@Cacheable的key、name等。注意:公共信息像全局变量一样,如果在局部没有声明,则用全局的值,如果局部有声明。则使用局部的值。也就是说,@CacheConfig的值可以局部被覆盖

四、总结

  1. 该篇文章介绍了Spring缓存抽象的其他注解以及简单使用。下一篇将带来SpringBoot与Redis的整合。敬请期待。谢谢~

评论