spring-redis缓存方案学习二:基于spring的@cache注解开发

原始template开发会入侵业务代码,与业务代码耦合。不容易阅读对管理业务代码造成了麻烦,并且会对事务产生影响。redis端抛出的异常会影响到数据库端的事务,使正常的业务数据一起回滚。为此spring提供了一套基于注解的缓存开发方案,解决了上述问题。

1.完善对spring对aop的依赖

spring的@cache注解是基于于aop实现。实际使用过程中,因为aop依赖不完整,会出现很多的异常情况。 
我遇到过抛出:no cache could be resolved for builder异常,@cachePut注解变成删除,@CacheEvict失效。因为完善spring对aop依赖至关重要。除了加入spring原生的aop组件外,还要加入以下依赖。

        <!-- aop 依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.10</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.10</version>
        </dependency>
        并且要在spring配置文件中添加以下字段,将jdk代理改为cglib代理。
        <aop:aspectj-autoproxy proxy-target-class="true">

2.在spring配置文件contex.txml导入对cache组件的支持

    <!-- 开启缓存注解驱动 -->
    <cache:annotation-driven/>
    <!-- 声明redis缓存的管理器 -->
    <bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
        <constructor-arg index="0" ref="redisTemplate"/>
    </bean>

3.在业务层添加cache注解

@Service
public class UserServiceImpl2 implements UserService {
    public static Logger logger = Logger.getLogger(UserServiceImpl2.class);
    @Autowired
    private UserMapper userMpper;//usermapper接口
    @Transactional
    @CachePut(key="#user.id",value="userCache")
    public User addUser(User user) {
        userMpper.insert(user);
        logger.info("向数据库添加用户");
        return user;
    }
    @Transactional
    @CacheEvict(key="#userId",value="user")
    public void deleteUser(String userId) {
        userMpper.deleteByPrimaryKey(userId);

    }
    @Transactional
    @CachePut(key="#user.id",value="user")
    public User updateUser(User user) {
        userMpper.updateByPrimaryKeySelective(user);
        return user;
    }
    @Transactional(readOnly=true)
    @Cacheable(key="#userId",value="user")
    public User queryUser(String userId) {
        logger.info("从数据库里取得用户");
        User user = userMpper.selectByPrimaryKey(userId);
        return user;
    }

}

@CachePut

@CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,方法调用成功后就会将参数缓存到redis中。

@CachePut 作用和配置方法

参数解释 
value 缓存的名称,必须指定至少一个 @CachePut(value=”my cache”) 
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 @CachePut(value=”testcache”,key=”#userName”) 
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 @CachePut(value=”testcache”,condition=”#userName.length()>2”)

@CachePut 注释,这个注释可以确保方法被执行,同时方法的返回值也被记录到缓存中,实现缓存与数据库的同步更新。

  • 实例
    @Test
    public void testAddUser() {
        User user = new User();
        user.setId("001");
        user.setUsername("username");
        user.setPassword("password");
        service.addUser(user);

    }
    @Transactional
    @CachePut(key="#user.id",value="userCache")
    public User addUser(User user) {
        userMpper.insert(user);
        logger.info("向数据库添加用户");
        return user;
    }

redis中生成的数据

@Cacheable 作用和配置方法 
@Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存

@Cacheable 主要的参数 
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如: 
@Cacheable(value=”mycache”) 或者 
@Cacheable(value={”cache1”,”cache2”} 
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如: 
@Cacheable(value=”userCahe”,key=”#userName”) 
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 例如: 
@Cacheable(value=”userCahe”,condition=”#userName.length()>0)

@Cacheable(key=”#user.id” value=”userCahe”),这个注释的意思是,当调用这个方法的时候,会查询传入对象的id,如果没有,则执行实际的方法(即查询数据库),并将执行的结果存入缓存中,否则返回缓存中的对象。

  • 实例
@Transactional(readOnly=true)
    @Cacheable(key="#userId",value="user")
    public User queryUser(String userId) {
        logger.info("从数据库里取得用户");
        User user = userMpper.selectByPrimaryKey(userId);
        return user;
    }

@CacheEvict

@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空

@CacheEvict 作用和配置方法

参数解释 
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 @CacheEvict(value=”my cache”) 
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 @CacheEvict(value=”testcache”,key=”#userName”) 
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 @CacheEvict(value=”testcache”,condition=”#userName.length()>2”) 
allEntries 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 @CachEvict(value=”testcache”,allEntries=true) 
beforeInvocation 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 @CachEvict(value=”testcache”,beforeInvocation=true)

  • 实例
    @Transactional
    @CacheEvict(key="#userId",value="user")
    public void deleteUser(String userId) {
        userMpper.deleteByPrimaryKey(userId);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值