常见的缓存有哪些?
1. mybatis一级缓存
public List<TrainQueryResp> queryAll(){
List<Train> trainList=selectAll();
LOG.info("再查一次");
trainList=selectAll();
return BeanUtil.copyToList(trainList,TrainQueryResp.class);
}
这段代码在查询火车的车次时会查询两次!但是当为该方法加入注解@Transactional,使该方法变为一个事务时,便只会查询一次(这就是事务的一级缓存,只要事务一旦结束,缓存就会消失)
public List<Train> selectAll(){
//按code升序排序,TrainExample是用来封装查询条件的
TrainExample trainExample=new TrainExample();
//orderByClause是用来指定排序的
trainExample.setOrderByClause("code asc");
return trainMapper.selectByExample(trainExample);
}
这是因为在第一个查询时,trainMapper.selectByExample(trainExample)会执行,然后将结果缓存,第二次查询时直接拿到结果
这样可以减少查询次数
一级缓存如何关闭呢?
在配置文件中加入
mybatis-configuration.local-cache-scope=session/statement
默认是session(会话)级别的,在一次会话中进行缓存
选用statement,每执行一次SQL,就会清空缓存
2. mybatis的二级缓存
二级缓存默认是关闭的,需要手动开启;
在需要使用二级缓存的Mapper文件中加入
<cache> </cache>
同时需要将实体类序列化,为该实体类implements Serializable即可
此后在第二次执行同一SQL语句时便不会再去查询数据库,而是直接使用缓存中的数据
那么二级缓存如何使之失效呢?
使用增删改SQL语句,即使没有改变数据,Mybatis都会将同个命名空间下的二级缓存清空
一级缓存的作用域是一次会话,二级缓存的作用域是同一命名空间
3. SpringBoot内置缓存
在pom文件中加入依赖(版本与springboot版本一致),同时在启动类中加入注解@EnableCaching
<!--spring内置缓存-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
目前做到这些可以说是支持缓存!
每个Service需要单独配置,才能自己开启;其中value值自定义
所以需要重写equals方法和hashCode方法使得对于我们要求的参数相同即可判断是相同的执行过程
4. redis缓存配置
//设置缓存类型为redis
spring.cache.type=redis
//使用缓存key的前缀
spring.cache.redis.use-key-prefix=true
spring.cache.redis.key-prefix=train_cache_
spring.cache.redis.cache-null-values=true
spring.cache.redis.time-to-live=60s
5. 缓存在高并发场景下的生产问题
6. 前端缓存
在很多个页面都会去获取火车车次数据,其实这个请求可以只请求一次,后面使用缓存即可(因为车站数据基本不会变化)
使用SeeionStorage,在一个js文件下定义
SESSION_ALL_TRAIN = "SESSION_ALL_TRAIN";
SessionStorage = {
get: function (key) {
var v = sessionStorage.getItem(key);
if (v && typeof(v) !== "undefined" && v !== "undefined") {
return JSON.parse(v);
}
},
set: function (key, data) {
sessionStorage.setItem(key, JSON.stringify(data));
},
remove: function (key) {
sessionStorage.removeItem(key);
},
clearAll: function () {
sessionStorage.clear();
}
};
使用:
/**
* 查询所有的车次,用于车次下拉框
*/
const queryAllTrain = () => {
let list = SessionStorage.get(SESSION_ALL_TRAIN);
if (Tool.isNotEmpty(list)) {
console.log("queryAllTrain 读取缓存");
trains.value = list;
} else {
axios.get("/business/admin/train/query-all").then((response) => {
let data = response.data;
if (data.su***ess) {
trains.value = data.content;
console.log("queryAllTrain 保存缓存");
SessionStorage.set(SESSION_ALL_TRAIN, trains.value);
} else {
notification.error({description: data.message});
}
});
}
};