mybatis缓存

为了提高数据利用率和减小服务器和数据库的压力,MyBatis 会对于一些查询提供会话级别的数据缓存,会将对某一次查询,放置到SqlSession 中,在允许的时间间隔内,对于完全相同的查询,MyBatis 会直接将缓存结果返回给用户,而不用再到数据库中查找.

MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候,如果判断先前有个完全一样的查询,会直接从缓存中直接将结果取出,返回给用户,不需要再进行一次数据库查询了.对于每一次查询,都会尝试根据查询的条件去本地缓存中查找是否在缓存中,如果在缓存中,就直接从缓存中取出,然后返回给用户;否则,从数据库读取数据,将查询结果存入缓存并返回给用户

一级缓存是怎样组织的

一级缓存是在sqlsession中控制的,SqlSession将它的工作交给了Executor执行器这个角色来完成,负责完成对数据库的各种操作。当创建了一个SqlSession对象时,MyBatis会为这个SqlSession对象创建一个新的Executor执行器,而缓存信息就被维护在这个Executor执行器中,缓存会存放在一个hashMap中.

一级缓存的生命周期

a.当会话结束时,SqlSession对象及其内部的Executor对象还有PerpetualCache对象也一并释放掉。

b. 如果SqlSession调用了close()方法,会释放掉一级缓存PerpetualCache对象,一级缓存将不可用;

c. 如果SqlSession调用了clearCache(),会清空PerpetualCache对象中的数据,但是该对象仍可使用;

d.SqlSession中执行了任何一个update操作(update()、delete()、insert()) ,都会清空PerpetualCache对象的数据,但是该对象可以继续使用;

如何确实两次查询是否完全相同

1.  传入的 statementId, statementId,它代表着你将执行什么样的Sql

2. 查询时要求的结果集中的结果范围 (通过rowBounds.offsetrowBounds.limit表示)

  MyBatis身提供的分页自功能是通过RowBounds来实现的,它通过rowBounds.offsetrowBounds.limit来过滤查询出来的结果集,这种分页功能是基于查询结果的再过滤,而不是进行数据库的物理分页

3.Sql语句字符串

4 传递给JDBC的参数值

mybatis将这些信息生成一个对应的Key对象,做为hashMap的key,然后可以通过比较hashCode是否一致

一级缓存的性能分析

1.MyBatis对会话(Session)级别的一级缓存设计的比较简单,就简单地使用了HashMap来维护,并没有对HashMap的容量和大小进行限制.

2.一级缓存是一个粗粒度的缓存,没有更新缓存和缓存过期的概念

注意

1、对于数据变化频率很大,并且需要高时效准确性的数据要求,我们使用SqlSession查询的时候,要控制好SqlSession的生存时间,SqlSession的生存时间越长,它其中缓存的数据有可能就越旧,从而造成和真实数据库的误差;同时对于这种情况,用户也可以手动地适时清空SqlSession中的缓存;

2、对于只执行、并且频繁执行大范围的select操作的SqlSession对象,SqlSession对象的生存时间不应过长。

 

二级缓存

MyBatis对二级缓存的支持粒度很细,它会指定某一条查询语句是否使用二级缓存。

Mapper中配置了<cache>,在<select> 节点中配置useCache="true"Mapper才会对此Select的查询支持缓存特性

二级缓存的实现

  LRU:(Least Recently Used),最近最少使用算法,即如果缓存中容量已经满了,会将缓存中最近做少被使用的缓存记录清除掉,然后添加新的记录;

     FIFO:(First in first out),先进先出算法,如果缓存中的容量已经满了,那么会将最先进入缓存中的数据清除掉;

     Scheduled:指定时间间隔清空算法,该算法会以指定的某一个时间间隔将Cache缓存中的数据清空;

 转:http://blog.csdn.net/luanlouis/article/details/41390801

posted @ 2017-12-21 19:52  ru2333  阅读(85)  评论(0编辑  收藏  举报