mybatis为减少 Java Application 与数 据库的交互次数,从而提升程 序的运行效率;提供了两级缓存机制,即为一级缓存和二级缓存。当然还有自定义缓存机制。
缓存的适用性:经常查询并且不经常改变的 数据的正确与否对最终结果影响不大的。 比如:一个公司的介绍,新闻等。。相反像即时性高,访问频繁变化快的数据,例如商品库存等不适合使用缓存。
作用域:同一个SqlSession对象,一般是默认开启的。缓存存储在内存当中。当使用同一个SqlSession对象查询相同的数据时,只会在第一次向数据库发送Sql语句。并将查询结果放在SqlSession中(作为缓存存在)。后续再次查询该同样的对象时,则会直接在缓存中查询该对象。即省略了数据库的访问。
当调用sqlsession的修改,添加,删除,commit(),close() 等方法时, 就会清空一级缓存。
1.对于某 Select Statement,根据该 Statement 生成 key;
2.判断在Local Cache中,该key是否 用对应的数据存在;
3.如果命中,则跳过查询数据库,继续往下走;
4.如果没命中,去数据库中查询数据,得到查询结果;
5.将key和查询到的结果作为 key 和 value,放入Local Cache 中;
6.将查询结果返回;
7 判断缓存级别是否为 STATEMENT 级别,如果是的话,清空本地缓存;
1.不同SqlSession对应不同的一级缓存
2.同一个SqlSession单查询条件不同
3.同一个SqlSession两次查询期间执行了任何一次增删改操作
4.同一个SqlSession两次查询期间手动清空了缓存
作用域:作用在同个namespace对象中,在映射文件中;namespace的值就是接口的全类名
(包名.类名),通过接口产生动态代理对象,namespace决定了ClssbjMapper的产生。即;
只要产生的XXXMapper对象来自同一个namemapper,则这些对象共享一个二级缓存。
如图:这里的两个动态代理对象同属一个ClassbjMapper.class,即共享一个二级缓存。
二级缓存默认存在,但需要手动打开。二级缓存存储在硬盘中。具体步骤:
1.A;在配置文件(config.xml)中开二级缓存:
B:在接口的定义上面直接使用@CacheNamespace 并将blocking设置为true,二级缓存就可以使用了
注意:
xml和接口中只要其中一个开启就可以了,AB不能同时存在,不然会报异常。
2.在具体的sqlmap中声明开启(mapper.xml中配置)
3.(只作了解,加深对存储位置(硬盘)的理解)对于MyBatis自带的二级缓存,实体类可以不用实现可序列化接口。在实体类及其级联属性中所包含的其他类全部要实现Serializable接口。因为二级缓存是要存储到硬盘中去,那从内存到硬盘就需要进行序列化操作,即序列化所涉及的所有实体类都要实现Serializable接口,表名这些类可以被序列化。
1.Mybatis 的二级缓存相对于一级缓存来说, 实现了缓存数据的共享,可控性也更强;
2.极大可能会出现错误数据,有设计上的缺陷安全使用的条件比较苛刻;
3.分布式环境下,必然会出现读取到错误 数据,所以不推荐使用。