您的位置:首页 > 其它

mybatis的缓存机制

2017-06-02 13:41 211 查看

1. 什么是一级缓存? 为什么使用一级缓存?

每当我们使用mybatis开启一次和数据库的会话的时候,mybatis会创建一个sqlsession对象表示一次数据库回话。在对数据库的一次会话中,我们很有可能在极短的时间内做出相同的查询语句,如果不采取一些措施的话, 在一定程度上会影响程序运行的效率的。为了解决这一问题,mybatis会在表示会话的sqlsession对象中建立一个简单的缓存(cache),将每次查询的结果缓存起来,当下次查询的时候,如果判断和先前有完全一样的查询,会直接从缓存中将结果取出,返回给用户,这样就不会再进行一次不必要的数据库查询了。如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。脏读:
脏读就是指读到还没完全弄好的数据。比如,你要读取数据库中的字段A、字段B,你读取时恰巧有其他用户正在更新这2个字段,而且是先更新A、再更新B,此时就可能会发生脏读:
1、如果都未更新你就读取了,或者都更新完了你才读取,这都不是脏读,因为你得到的是更新前的有效值,或完全更新后的值。
2、如果那个用户更新一半你就读取了,也就是说更新了A,正打算要更新B但尚未更新时,你就读取了,此时你得到的就是脏数据。
避免脏读的办法就是采取事务,使得他用户正在更新时锁定数据库,阻止你读取,直至全部完成才让你读取。
一级缓存基于 PerpetualCache 的HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有缓存(cache)就将清空。(PerpetualCache实现原理其实很简单,其内部就是通过一个简单的HashMap<k,v>来实现的,没有其他的任何限制。)2.一级缓存的生命周期有多长?a.MyBatis在开启一个数据库会话时,会创建一个新的SqlSession对象,SqlSession对象中会有一个新的Executor对象,Executor对象中持有一个新的PerpetualCache对象;当会话结束时,SqlSession对象及其内部的Executor对象还有PerpetualCache对象也一并释放掉。b.如果SqlSession调用了close()方法,会释放掉一级缓存PerpetualCache对象,一级缓存将不可用;c.如果SqlSession调用了clearCache(),会清空PerpetualCache对象中的数据,但是该对象仍可使用;d.SqlSession中执行了任何一个update操作(update()、delete()、insert()),都会清空PerpetualCache对象的数据,但是该对象可以继续使用;3.Cache中Map的key值:CacheKey我们知道,Cache最核心的实现其实就是一个Map,将本次查询使用的特征值作为key,将查询结果作为value存储到Map中。现在最核心的问题出现了:怎样来确定一次查询的特征值?换句话说就是:怎样判断某两次查询是完全相同的查询?也可以这样说:如何确定Cache中的key值?MyBatis认为,对于两次查询,如果以下条件都完全一样,那么就认为它ad4a们是完全相同的两次查询:1. 传入的statementId   传入的statementId,对于MyBatis而言,你要使用它,必须需要一个statementId,它代表着你将执行什么样的Sql;2. 查询时要求的结果集中的结果范围(结果的范围通过rowBounds.offset和rowBounds.limit表示);3. 这次查询所产生的最终要传递给JDBC java.sql.Preparedstatement的Sql语句字符串(boundSql.getSql())4. 传递给java.sql.Statement要设置的参数值综上所述,CacheKey由以下条件决定:statementId  + rowBounds  + 传递给JDBC的SQL  + 传递给JDBC的参数值原文: http://www.xuebuyuan.com/2231229.html
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: