mybatis 缓存 cache

mybatis会将查询出来的数据存放到缓存中,当再次查询重复数据时,直接从缓存中取出,避免重复查询相同数据而浪费系统资源

mybatis缓存分为:一级缓存 、二级缓存

 

  • 一级缓存 (作用域比较小)

一级缓存:本地缓存(sqlSession级别缓存),与数据库同一次会话(sqlSession)期间查询到的数据会被放到本地缓存中,如果直接从缓存中获取,不会再次向数据库查询数据
mybatis一直默认开启一级缓存,不同的sqlSession级别缓存,数据不可共用

一级缓存失效情况(没有使用到当前一级缓存的情况,如果没有使用,效果就是第二次查询相同语句还需要向数据库发送sql)
失效情况:
    1.sqlSession不同
    2.当sqlSession对象相同,查询条件不同,原因第一次查询的过程中一级缓存中没有第二次查询需要的数据
    3.当sqlSession对象相同,两次查询之间进行了增删改查的操作
    4.当sqlSession对象相同,手动清除了一级缓存中的数据

 

  • 二级缓存 (全局缓存)  基于namespace(就是sql的mapper.xml文件)级别的缓存

    1.一个会话查询出一条数据,这个数据会被放到当前会话的一级缓存中,如果会话没有关闭,第二次再查询,直接从一级缓存中取出
    2.如果当前会话被关闭掉,那么对应的一级缓存没有了,但是mybatis会将一级缓存数据保存到二级缓存中,如果再次创建一次会话,在重新发送查询,返回的数据可以直接从第二级缓存中进行获取
    二级缓存是基于一级缓存的

 

使用二级缓存

  1.在mybatis全局配置文件中配置: setting标签下 --->> <setting name="cacheEnabled" value="true"/>

 <settings>
    <!-- 开启二级缓存: 如果设置为false二级缓存被关闭,一级缓存依然可以使用  -->
    <setting name="cacheEnabled" value="true"/> 
 </settings>

 2.在mapper.xml中配置使用二级缓存  <cache>

<?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="com.mybatis.mapper.EmployeeMapper">
 <cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024">
	<!-- 
	cache 标签用于开启二级缓存策略  
	  属性:
		eviction 缓存的回收策略   属性值: LRU(回收很少使用的对象)   FIFO(对象先进先出)
		flushInterval 刷新缓存间隔,配置毫秒数,默认不清空
		size 缓存的引用数目  (设置任意正整数 默认1024)
		readOnly 是否只读  设置true代表只读  false不是只读
		type:使用第三方缓存方案创建适配器,来完全覆盖缓存行为
	 -->
 </cache>      
 ......................省略
</mapper> 


3.bean实体类要实现Serializable接口(序列化)  二级缓存内部是基于序列化的

public class Employee implements Serializable {
	
  private static final long serialVersionUID = 1L;
  //........................
}

 

有关于二级缓存之 SQL的  mapper.xml 文件配置属性:

1. select 标签属性:useCache="true"  默认为true ,代表缓存都可以使用
2. nsert update  delete 标签中有一个默认属性:flushCache(代表执行完之后清空缓存数据) 

 

 

查询过程: 二级缓存 -->> 一级缓存 -->> 数据库

会话查询数据之后,会把数据先存放到自己的一级缓存中,如果会话关闭,会把数据存放到二级缓存中。
第二次查询先看二级缓存中有没有对应的,如果二级缓存中没有,就去一级缓存中找,
如果一级缓存也没有,则重新向数据库发送语句进行查找

 

ps:

在两次查询之间进行新增修改删除的任意一个操作,对一级缓存和二级缓存都会影响
原因是在mapper文件中的insert update delete 默认有一个属性:flushCache=“true” 表示清空缓存

 

例:

class Test{
 public static void main(String[] args) throws IOException {
		
	String resource = "mybatis_config.xml";
	InputStream inputStream = Resources.getResourceAsStream(resource);

	SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		
	//每一个sqlSession对象都拥有自己的缓存
	SqlSession session1 = sqlSessionFactory.openSession();
	SqlSession session2 = sqlSessionFactory.openSession();
		
	//利用反射创建employee的持久层实现类
	EmployeeMapper mapper1 = session1.getMapper(EmployeeMapper.class);
	EmployeeMapper mapper2 = session2.getMapper(EmployeeMapper.class);
		
		
		
	Employee emp1 = mapper1.findEmpById(3);
	System.out.println("emp1=========="+emp1);
		
	/*
         * 关闭Session1  
	 * 关闭之后,该session中一级缓存的数据将被mybatis保存到二级缓存中
	 */
	session1.close(); 
		
	//查询同样的数据,从二级缓存中取出
	Employee emp2 = mapper2.findEmpById(3);
	System.out.println("emp2=========="+emp2);
		
} }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值