常见的缓存有哪些?
- Mysql一级缓存
- Mysql二级缓存
- 本地缓存
- 分布式缓存
- 前端h5的sessionStorage
- 前端h5的localStorage
1. mybatis一级缓存
![![[Pasted image 20240306094236.png]]](https://img-blog.csdnimg.cn/direct/eac1a31b3ef445ecab5c9aae8b96805f.png)
publicList<TrainQueryResp>queryAll(){List<Train> trainList=selectAll();LOG.info("再查一次");
trainList=selectAll();returnBeanUtil.copyToList(trainList,TrainQueryResp.class);}
这段代码在查询火车的车次时会查询两次!但是当为该方法加入注解@Transactional,使该方法变为一个事务时,便只会查询一次(这就是事务的一级缓存,只要事务一旦结束,缓存就会消失)
publicList<Train>selectAll(){//按code升序排序,TrainExample是用来封装查询条件的 TrainExample trainExample=newTrainExample();//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>
![![[Pasted image 20240306101418.png]]](https://img-blog.csdnimg.cn/direct/898d3d30721e4f6bb2faa17911a2a93d.png)
同时需要将实体类序列化,为该实体类implements Serializable即可
![![[Pasted image 20240306101432.png]]](https://img-blog.csdnimg.cn/direct/e8f1fe7ea18b44a6afadc4e62d7a069f.png)
此后在第二次执行同一SQL语句时便不会再去查询数据库,而是直接使用缓存中的数据
那么二级缓存如何使之失效呢?
使用增删改SQL语句,即使没有改变数据,Mybatis都会将同个命名空间下的二级缓存清空
一级缓存的作用域是一次会话,二级缓存的作用域是同一命名空间
3. SpringBoot内置缓存
在pom文件中加入依赖(版本与springboot版本一致),同时在启动类中加入注解@EnableCaching
<!--spring内置缓存--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency>
目前做到这些可以说是支持缓存!
每个Service需要单独配置,才能自己开启;其中value值自定义
![![[Pasted image 20240306103607.png]]](https://img-blog.csdnimg.cn/direct/b88002fe65af43d39fa43b9b937d7e8c.png)
所以需要重写equals方法和hashCode方法使得对于我们要求的参数相同即可判断是相同的执行过程
![![[Pasted image 20240306103941.png]]](https://img-blog.csdnimg.cn/direct/f7ed7b4377e743fcbdbef3155313e218.png)
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. 缓存在高并发场景下的生产问题
![![[Pasted image 20240306112132.png]]](https://img-blog.csdnimg.cn/direct/b3af323155174d738b975281cb43623c.png)
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"){returnJSON.parse(v);}},set:function(key, data){
sessionStorage.setItem(key,JSON.stringify(data));},remove:function(key){
sessionStorage.removeItem(key);},clearAll:function(){
sessionStorage.clear();}};
使用:
/**
* 查询所有的车次,用于车次下拉框
*/constqueryAllTrain=()=>{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.success){
trains.value = data.content;
console.log("queryAllTrain 保存缓存");
SessionStorage.set(SESSION_ALL_TRAIN, trains.value);}else{
notification.error({description: data.message});}});}};
版权归原作者 小黄妖怪 所有, 如有侵权,请联系我们删除。