19.2.1表达式引用
#Argument:
- 是指的方法中的参数
#result:
- 方法返回的结果.不可以用于@Cacheable,因为当前方法可能不被执行
19.2.2注解
19.2.2.1 @EnableCaching
- 相当于xml中的 <cache:annotation-driven />
- 开启注解缓存管理(可以使用注解来管理缓存-@cacheable等)
19.2.2.2 @Cacheable
- 注解方法,表示在进入该方法前会先进入spring缓存中查找对应的key值,如果找到则直接返回结果
如果没有找到则执行当前方法,并将最后的结果保存到缓存中.
- 只能用于有返回值的方法
- 一般用于查找方法
@Override
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
@Cacheable(value = "cacheManagerTest", key = "'redis_role_'+#id")
public Role getRole(int id) {
return roleMapper.getRole(id);
}
注意:配置文件会设置缓存的超时时间,超时时间以第一次注册到缓存时候为效.意思是若第一次设置为10分钟,之后立即重启设置为1秒.当前最近的设置无效,要等到上次设置失效后,本次设置才生效.
19.2.2.3 @Cacheput
- 注解方法.spring会先执行该注解方法,之后将返回的结果更新到spring缓存里.
- 该注解只能注解有返回值的方法
- 一般用于insert/update方法
@Override
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
@CachePut(value = "cacheManagerTest",key = "'redis_role_'+#result.id")
public Role insert(Role role) {
roleMapper.insert(role);
return role;
}
19.2.2.4 @CacheEvict
- 主要用于移除缓存中的键值对.用于删除方法.
- allEntries属性若为true,则删除缓存中所有的键值对.慎用
- beforeInvocation默认为false,即在执行改方法后删除缓存中的键值对.若为true,则在执行该方法前删除键值对.
@Override
@CacheEvict(value = "cacheManagerTest", key = "'redis_role_'+#id", beforeInvocation = false)
public void delete(int id) {
Role role1 = (Role) redisTemplate.opsForValue().get("redis_role_"+id);
System.out.println( "delete redis缓存中: " + role1.toString()+"\n");
roleMapper.delete(id);
}
19.2.2.5 @Repository
- 注解的类会生成bean注册到spring ioc容器.
- 表示对应的bean为持久化的(数据库相关)
19.2.3配置缓存管理
- 启动注解缓存管理
<beans
xmlns:cache="http://www.springframework.org/schema/cache"
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-4.0.xsd">
<cache:annotation-driven cache-manager="cacheManager"/>
- <cache:annotation-driven cache-manager="cacheManager"/>等同于@EnableCaching
- 如果cache-manager的值为cacheManager,可以不配置.spring默认为”cacheManager”
2.数据库Redis缓存管理配置
<!--数据库Redis缓存管理配置-->
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
<!--上文中已经说过了-->
<constructor-arg ref="redisTemplate"/>
<!--单位秒-->
<property name="defaultExpiration" value="60"/>
<property name="cacheNames">
<list>
<value>cacheManagerTest</value>
</list>
</property>
</bean>
19.2.4示例
- Role.java
@Alias(value = "role")
public class Role implements Serializable {
private int id;
private String name;
private SexEnum sex;
public Role(){}
public Role(Integer id, String name ) {
this.id = id;
this.name = name;
}
******getter and setter******
}
RoleSerivce.java
public interface RoleService {
public void delete(int id);
public Role getRole(int id);
public Role update(Role role);
public Role insert(Role role);
}
- NewRoleMapper.java
@Repository
public interface NewRoleMapper {
public Role getRole(int id);
public void update(Role role);
public void delete(int id);
public void insert(Role role);
}
4.testMapper19.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Nineteen.NewRoleMapper">
<resultMap id="role" type="Dao.Role">
<result property="id" column="id"></result>
<result property="name" column="name"/>
<result property="sex" column="sex" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>
</resultMap>
<select id="getRole" parameterType="int" resultMap="role">
select * from Role where id = #{id}
</select>
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
insert into Role(id, name) values (#{id},#{name})
</insert>
<delete id="delete" >
delete from Role where id=#{id}
</delete>
<update id="update">
update Role set name = #{name} where id = #{id}
</update>
</mapper
5.myBatis配置文件:spring-MyBatis-conf19.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases >
<package name="Three.Dao"/>
</typeAliases >
<mappers>
<mapper resource="mapper/testMapper19.xml"></mapper>
</mappers>
</configuration>
6.spring配置文件:spring-ceshi-mybatis19.xml
<context:component-scan base-package="Three,Nineteen"/>
<import resource="classpath:spring-mvc-redis.xml"/>//引用之前的配置文件
<cache:annotation-driven cache-manager="cacheManager"/>
<!--mybatis数据库基础配置-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.mariadb.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/lccTest2"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</bean>
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:MyBatisTest/spring-MyBatis-conf19.xml"/>
</bean>
<bean id="sessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="sqlSessionFactoryBean"/>
<constructor-arg value="REUSE"/>
</bean>
<!--扫描Repository标志的bean,生成和mapper相关匹配的bean-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="Nineteen"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"/>
<property name="annotationClass" value="org.springframework.stereotype.Repository"/>
</bean>
<!--数据库事务管理配置-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--数据库Redis缓存管理配置-->
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
<constructor-arg ref="redisTemplate"/>
<!--单位秒-->
<property name="defaultExpiration" value="60"/>
<property name="cacheNames">
<list>
<value>cacheManagerTest</value>
</list>
</property>
</bean>
7.RoleServiceImpl.java
@Service
public class RoleServiceImpl implements RoleService {
@Autowired
private NewRoleMapper roleMapper;
@Autowired
private RedisTemplate redisTemplate;
@Override
@CacheEvict(value = "cacheManagerTest", key = "'redis_role_'+#id", beforeInvocation = false)
public void delete(int id) {
Role role1 = (Role) redisTemplate.opsForValue().get("redis_role_"+id);
System.out.println( "delete redis缓存中: " + role1.toString()+"\n");
roleMapper.delete(id);
}
@Override
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
@Cacheable(value = "cacheManagerTest", key = "'redis_role_'+#id")
public Role getRole(int id) {
return roleMapper.getRole(id);
}
@Override
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
@CachePut(value = "cacheManagerTest",key = "'redis_role_'+#result.id")
public Role update(Role role) {
roleMapper.update(role);
Role role1 = (Role) redisTemplate.opsForValue().get("redis_role_"+role.getId());
System.out.println( "service update redis缓存中: " + role1.toString()+"\n");
return role;
}
@Override
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
@CachePut(value = "cacheManagerTest",key = "'redis_role_'+#result.id")
public Role insert(Role role) {
roleMapper.insert(role);
return role;
}
}
8.运行方法
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:MyBatisTest/spring-ceshi-mybatis19.xml"})
@EnableTransactionManagement
public class Test1 {
@Autowired
RoleService roleService;
@Autowired
RedisTemplate redisTemplate;
@Autowired
private NewRoleMapper roleMapper;
@Test
public void test1() {
int id=11;
roleService.insert(new Role(id,"redis"+id));
Role role1 = (Role) redisTemplate.opsForValue().get("redis_role_"+id);
System.out.println( "insert后redis缓存中: " + role1.toString()+"\n");
roleService.update(new Role(id,"redis-update"+id ));
System.out.println("update后缓存中数据: "+roleService.getRole(id).toString());
System.out.println("update后数据库中数据:"+roleMapper.getRole(id).toString()+"\n");
roleService.delete(id);
/* System.out.println("delete后缓存中数据: "+roleService.getRole(id).toString());*/
System.out.println("delete后数据库中数据:"+roleMapper.getRole(id));
}
}
结果:
insert后redis缓存中: Role{id=11, name='redis11'}
service update redis缓存中: Role{id=11, name='redis11'}
update后缓存中数据: Role{id=11, name='redis-update11'}
update后数据库中数据:Role{id=11, name='redis-update11'}
delete redis缓存中: Role{id=11, name='redis-update11'}
delete后数据库中数据:null