打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Spring整合Redis作为缓存
采用Redis作为Web系统的缓存。用Spring的Cache整合Redis。一、关于redis的相关xml文件的写法
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- 开启缓存注解 -->
<cache:annotation-driven />    <!-- jedis客户端连接工厂 --><bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="192.168.1.200" p:port="6379"/>
<!-- redisTemplate模板 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="jedisConnectionFactory"/>
<!-- redis缓存管理器 -->
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager" c:template-ref="redisTemplate"/>
</beans>
二、实体类
public class Student implements Serializable{
/**
*
*/
private static final long serialVersionUID = -4676194082313592019L;
private Integer id;
private String name;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
三、数据访问层
public interface StudentMapper {
@Insert("insert into student(id,name,age) values(#{id},#{name},#{age})")
public void insert(Student student);
@Delete("delete from student where id = #{id}")
public void delete(@Param("id")Integer id);
@Update("update student set name=#{name},age=#{age} where id=#{id}")
public void update(Student student);
@Select("select * from student where id=#{id}")
public Student queryById(@Param("id")Integer id);
}
四、业务处理层(关键)
public interface IStudentService {
public void add(Student student);
public void delete(Integer id);
public void update(Student student);
public Student queryById(Integer id);
}
public class StudentServiceImpl extends BaseService implements IStudentService{
private StudentMapper mapper;
@CachePut(key="#student.id",value="student")
@Override
public void add(Student student) {
mapper = writableSQLSession.getMapper(StudentMapper.class);
mapper.insert(student);
}
@Override
public void delete(Integer id) {
mapper = writableSQLSession.getMapper(StudentMapper.class);
mapper.delete(id);
}
@Override
public void update(Student student) {
mapper = writableSQLSession.getMapper(StudentMapper.class);
mapper.update(student);
}
@Cacheable(key="#id",value="student")
@Override
public Student queryById(Integer id) {
mapper = readonlySQLSession.getMapper(StudentMapper.class);
return mapper.queryById(id);
}
}
最重要的三个注解是@Cacheable()和@CacheEvict()和@CachePut()
对于缓存声明,缓存抽象类提供两个Java注解:@Cacheable和@CacheEvict,这两个注解可以允许方法触发缓存或者缓存抽取。
@Cacheable缓存
应用到读取数据的方法上,即可缓存的方法,如查找方法。
就像注解名字的含义一样,@Cacheable用于区别可缓存的方法,指的是方法运行的结果被装入缓存的方法,因此,在随后的方法调用中,在缓存的值被返回,在实际上没有执行这个方法。最简单的构成,注解声明需要和被缓存的方法有关系的缓存名字:
@Cacheable("books")
public Book findBook(ISBN isbn) {...}
在上面的片段,findBook方法是和名字为books的缓存有关系的。方法每次被调用,这个缓存被检查去查看是否这个调用已经执行并且没有被重复。在大多数的情况下,只有一个缓存被声明,注解允许多个被指定的名字以至于不知一个缓存被正在使用。在这种情况下,每个缓存将会在执行方法之前被检查,如果至少一个缓存被选中,那么相关的值将被返回:
(注意:所有其他的没有包含这个方法的缓存将会被更新,即使这个被缓存的方法实际上没有被执行)
@Cacheable({ "books", "isbns" })
public Book findBook(ISBN isbn) {...}
默认键的生成
由于缓存实际上是键值对存贮的,一个被缓存的方法每一次的调用需要被转换成一个合适的键为了缓存访问。在这个盒子之外,缓存抽象类用一个简单的KeyGenerator(键生成器)基于以下的算法:
1.如果没有给参数,返回SimpleKey.EMPTY。
2.如果仅仅给了一个参数,返回那个实例。
3.如果不只一个参数被指定,返回一个SimpleKey包含所有参数。
只要参数具有natural keys并且实现有效的hashCode()和equals()方法,这种处理方式对于大多数用例运行完美;如果这不符合这种场景,键的生成策略需要改变。
提供一个不同的默认键生成器,需要实现org.springframework.cache.KeyGenerator接口。一旦配置,这个生成器将会用于每个没有特殊指定它自己的键生成策略的声明中。
用户自定义键生成器声明
因为缓存是一个通用类,它非常像有多种不能简单映射在缓存结构的顶部的签名的目标方法。当目标方法有多个超出了适用于缓存的参数时,这将变得明显。例如:
@Cacheable("books")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
第一眼看去,两个布尔型的参数影响找书的方式,他们对于缓存是没用的。
对于这种场景,@Cacheable注解允许用户通过key属性指定键的生成策略。开发和可以用SpEL去获取参数(或者他们包含的属性),执行的方式甚至不用写任何代码或者实现任何借口调用不同的方法。这是在默认生成器之外推荐的方法。
@CachePut
应用到写数据的方法上,如新增/修改方法
@CacheEvict
即应用到移除数据的方法上,如删除方法
提供的SpEL上下文数据
Spring Cache提供了一些供我们使用的SpEL上下文数据,下表直接摘自Spring官方文档:
名字位置描述示例
methodName
root对象
当前被调用的方法名
#root.methodName
method
root对象
当前被调用的方法
#root.method.name
target
root对象
当前被调用的目标对象
#root.target
targetClass
root对象
当前被调用的目标对象类
#root.targetClass
args
root对象
当前被调用的方法的参数列表
#root.args[0]
caches
root对象
当前方法调用使用的缓存列表(如@Cacheable(value={"cache1", "cache2"})),则有两个cache
#root.caches[0].name
argument name
执行上下文
当前被调用的方法的参数,如findById(Long id),我们可以通过#id拿到参数
#user.id
result
执行上下文
方法执行后的返回值(仅当方法执行之后的判断有效,如‘unless’,'cache evict'的beforeInvocation=false)
#result
条件缓存
有时,一个方法不总是适用于缓存。缓存注解通过带有SpEL表达式的conditional参数来评估是true或者false能够达到这种功能。如果返回时true,那么这个方法被缓存,如果不是,这个方法不会被缓存。一个例子,下面的方法将会被缓存,仅当参数name的长度小于32的时候:
@Cacheable(value="book", condition="#name.length < 32")
public Book findBook(String name)
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Spring使用Cache、整合Ehcache
Spring 整合 Ehcache 管理缓存详解
Spring极速集成注解redis实践
Spring Boot 基于注解的 Redis 缓存使用
Spring 思维导图,让 Spring 不再难懂(cache篇)
Spring Boot应用的测试——Mockito
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服