mybatis的一级、二级缓存

mybatis的一级缓存和二级缓存

 

mybatis 的一级缓存:sqlsession 级别的,内部维护的其实就是Map,其缓存对象是PerpetualCache。

  1、MyBatis的一级缓存是SqlSession级别的,但是它并不定义在SqlSessio接口的实现类DefaultSqlSession中,而是定义在DefaultSqlSession的成员变量Executor中,Executor是在openSession的时候被实例化出来的,它的默认实现为SimpleExecutor
  2、MyBatis中的一级缓存,与有没有配置无关,只要SqlSession存在,MyBastis一级缓存就存在,localCache的类型是PerpetualCache,它其实很简单,一个id属性+一个HashMap属性而已,id是一个名为"localCache"的字符串,HashMap用于存储数据,Key为CacheKey,Value为查询结果
  3、MyBatis的一级缓存查询的时候默认都是会先尝试从一级缓存中获取数据的,但是我们看第6行的代码做了一个判断,ms.isFlushCacheRequired(), 即想每次查询都走DB也行,将绑定并在MyBatis启动的时候存入Configuration中:
protected final Map mappedStatements = new StrictMap("Mapped Statements collection");
因此MyBatis二级缓存的生命周期即整个应用的生命周期,应用不结束,定义的二级缓存都会存在在内存中。
从这个角度考虑,为了避免MyBatis二级缓存中数据量过大导致内存溢出,MyBatis在配置文件中给我们增加了很多配置例如size(缓存大小)、
flushInterval(缓存清理时间间隔)、eviction(数据淘汰算法)来保证缓存中存储的数据不至于太过庞大。


可用的收回策略有:

【默认】LRU——最近最少使用的:移除最长时间不被使用的对象 
 FIFO——先进先出的:按对象进入缓存的顺序来移除他们 
 SOFT——软引用:移除基于垃圾回收器状态和软引用规则的对象 
 WEAK——弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
flushInterval(刷新间隔)可以被设置为任意的正整数(60*60*1000这种形式是不允许的),而且它们代表一个合理的毫秒形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。 
size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是1024. 
readOnly(只读)属性可以被设置为true或false。只读的缓存会给所有调用者返回缓存对象的相同实例,因此这些对象不能被修改,这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过发序列化)。这会慢一些,但是安全,因此默认是false。

 

package springSourseAnalyes.sqlsessionMybatis;

import java.util.List;

import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.webTest.inputData.dao.GuiJiResultDateDao;


//@Service("cacheServiceImpl")
public class SqlSessionLocalCacheServiceImpl implements BeanFactoryAware{
	
	
	private BeanFactory beanFactory;

//	@Autowired
	GuiJiResultDateDao guiJiResultMapper;
	
	//如果再方法中调用事务方法,这时事务是失效的,,解决方法如下,
	//获取事务的代理类,不然事务无效 ,.需要在配置文件中配置aop:aspectj-autoproxy 配置expose-proxy为true,或者
//	使用spring3.1.2以上版本的注解方式@EnableAspectJAutoProxy(proxyTargetClass="true",exposeProxy="true")
//			((SqlSessionLocalCacheServiceImpl)AopContext.currentProxy()).getSqlData();
	public void getSqlDataTran(){
		((SqlSessionLocalCacheServiceImpl)AopContext.currentProxy()).getSqlData();
//		this.getSqlData();
	}
	
	@Transactional
	public void getSqlData(){
//		guiJiResultMapper.insertOrder(232131321);
//		int i = 1/0;
		List text = guiJiResultMapper.getText("1111");
		
		List text1 = guiJiResultMapper.getText("1111");
		
		System.out.println(text.size() + text1.size());
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		// TODO Auto-generated method stub
		this.beanFactory = beanFactory;
	}
}
 
  

 

你可能感兴趣的:(mybatis)