• java用注解实现redis缓存


    用注解实现redis缓存

    @CacheConfig

    主要用于配置该类中会用到的一些共用的缓存配置。示例:

    @CacheConfig(cacheNames = "users")
    public interface UserService {...}
    

    配置了该数据访问对象中返回的内容将存储于名为users的缓存对象中,我们也可以不使用该注解,直接通过@Cacheable自己配置缓存集的名字来定义。

    @Cacheable

    可以标记在一个方法上,也可以标记在一个类上,表示该方法/类是支持缓存的;Spring会在其被调用后将其返回值缓存起来。下次利用同样的参数来执行该方法时可以直接从缓存中获取结果。
    参数介绍
    • value、cacheNames:两个等同的参数(cacheNames为Spring 4新增,作为value的别名),用于指定缓存存储的集合名。由于Spring 4中新增了@CacheConfig,因此在Spring 3中原本必须有的value属性,也成为非必需项了
    • key:缓存对象存储在Map集合中的key值,非必需,缺省按照函数的所有参数组合作为key值,若自己配置需使用SpEL表达式,比如:@Cacheable(key = "#p0"):使用函数第一个参数作为缓存的key值,更多关于SpEL表达式的详细内容可参考官方文档
    • condition:缓存对象的条件,非必需,也需使用SpEL表达式,只有满足表达式条件的内容才会被缓存,比如:@Cacheable(key = "#p0", condition = "#p0.length() < 3"),表示只有当第一个参数的长度小于3的时候才会被缓存。
    • unless:另外一个缓存条件参数,非必需,需使用SpEL表达式。它不同于condition参数的地方在于它的判断时机,该条件是在函数被调用之后才做判断的,所以它可以通过对result进行判断。
    • keyGenerator:用于指定key生成器,非必需。若需要指定一个自定义的key生成器,我们需要去实现org.springframework.cache.interceptor.KeyGenerator接口,并使用该参数来指定。需要注意的是:该参数与key是互斥的
    • cacheManager:用于指定使用哪个缓存管理器,非必需。只有当有多个时才需要使用
    • cacheResolver:用于指定使用那个缓存解析器,非必需。需通过org.springframework.cache.interceptor.CacheResolver接口来实现自己的缓存解析器,并用该参数指定。
    示例如下:

    @Cacheable(value = "user", key = "#id")
    User selectUserById(final Integer id);
    

    • 关于使用key属性自定义key
    用来指定Spring缓存方法的返回结果时对应的key,支持SpringEL表达式。没有指定该属性时,Spring将使用默认策略生成key。

    使用方法参数时我们可以直接使用“#参数名”或者“#p+参数的index”(参数index按照顺序从0开始)
    例子:

     			@Cacheable(value="users", key="#id")
      			 public User find(Integer id) {
      			    return null;
      			 }
       			@Cacheable(value="users", key="#p0")
       			public User find(Integer id) {
      			    return null;
       			}
       			@Cacheable(value="users", key="#user.id")
       			public User find(User user) {
         				 return null;
       			}
       			@Cacheable(value="users", key="#p0.id")
     			  public User find(User user) {
      			    	return null;
     			  }
    

    @CachePut

    应用到写数据的方法上,如新增/修改方法,调用方法时会自动把相应的数据放入缓存,示例如下:

    @CachePut(value = "user", key = "#user.id")  
    public User save(User user) {  
        users.add(user);  
        return user;  
    }  
    

    此时会以user.id做为缓存key,返回结果user做为值
    @CachePut的参数与@Cacheable类似
    @CacheEvict
    应用到移除数据的方法上,如删除方法,调用方法时会从缓存中移除相应的数据,示例如下:

    @CacheEvict(value = "user", key = "#id")
    void delete(final Integer id);
    

    参数介绍
    除了同@Cacheable一样的参数之外,@CacheEvict还有下面两个参数:
    • allEntries:非必需,默认为false。当为true时,会移除所有数据
    • beforeInvocation:非必需,默认为false,会在调用方法之后移除数据。当为true时,会在调用方法之前移除数据。

    @解决数据一致性的两种方式

    1. 使用@CachePut

    在“查询”方法上添加@Cacheable(value=”testValue”, key= “#testKey”)注解,对方法的返回值进行缓存,在“新增/修改”方法上添加@CachePut(value=”testValue”, key= “#testKey”)注解,当方法调用成功后,会对缓存testValue上key值为testKey的缓存进行更新,更新内容为“新增/修改”的返回值,因此“查询”方法与“新增/修改”方法的返回值类型应该一致。
    E.g.
    user实体包含属性: id / username / userage / usersex

    @CachePut(value = "user", key = "#user.id#user.name#user.pass")  //用id作为缓存的key
    public User get(User user) {  
        User user = users.getById(user.id);  //id = 123; username = “zhangsan”; userage = 18; usersex = “1”;
        return user;  
    }  
    @CachePut(value = "user", key = "#user.id")  //方法调用成功后更新key = 123 的缓存
    public User update(User user) {  
        userService.updateById(user);  //id = 123; username = “lisi”; 
        return user;  
    }  
    

    执行update方法后,当再次调用get(User user)查询方法时,redis内user缓存上key = 123仍然存在且user实体会变为 :(id = 123; username = “zhangsan”; userage = ; usersex = “”;)
    由于返回值造成了缓存与数据库数据不一致的问题。

    2. 使用@CacheEvict

    在“查询”方法上添加@Cacheable(value=”testValue”, key= “#testKey”)注解,对方法的返回值进行缓存,在“新增/修改”方法上添加@CacheEvict(value=”testValue”, key= “#testKey”)注解,当方法调用成功后,会删除缓存testValue上key值为testKey的缓存。
    由于缓存中testValue上的key = 123已经被删除,再次调用“查询”方法时,会直接查库,因此不存在数据不一致的问题。

    @Cacheable注解不生效的问题

    1.内部方法的调用导致@Cacheable失效

    @Cacheable是基于Spring AOP代理类,内部方法调用是不走代理的,@Cacheable是不起作用的

    2.缓存的对象必须实现Serializable

    问题

    1.针对key的失效时间设置,未实现
    2.分页时的缓存较复杂,未实现

  • 相关阅读:
    Scala学习笔记
    flume ng 1.3 安装(转)
    学习scala trait
    scala性能测试
    scala容器使用
    hdu 4607 Park Visit
    FZU 1591 Coral的烦恼
    fzu 1675 The Seventy-seven Problem
    hdu 4602 Partition
    zoj 1842 Prime Distance
  • 原文地址:https://www.cnblogs.com/healkerzk/p/13576209.html
Copyright © 2020-2023  润新知