Mybatis一/二级缓存
1. 一级缓存sqlSession
各个sqlSession之间是互相隔离的,不会回想调用缓存。
logger.info("开启第一个session");
session = sqlSessionFactory.openSession();
BookMapper bookMapper1 = session.getMapper(BookMapper.class);
logger.info("同一个session查询1");
Book book = bookMapper1.findById(30);
logger.info("同一个session查询2");
Book book1 = bookMapper1.findById(30);
logger.info("查询2结束");
logger.info("开启第二个session");
SqlSession session2 = sqlSessionFactory.openSession();
BookMapper bookMapper2 = session2.getMapper(BookMapper.class);
Book book2 = bookMapper2.findById(30);
logger.info("查询结束");
十一月 10, 2017 9:58:06 下午 mybatis.controller.Test main 信息: 开启第一个session 十一月 10, 2017 9:58:06 下午 mybatis.controller.Test main 信息: 同一个session查询1 第一次查询,打开数据库一个连接,查询并保存缓存 Opening JDBC Connection Created connection 981661423. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.Connection@3a82f6ef] ==> Preparing: select bid, author, name, title, price, des from t_book where bid = ? ==> Parameters: 30(Integer)
十一月 10, 2017 9:58:06 下午 mybatis.controller.Test main信息: 同一个session查询2十一月 10, 2017 9:58:06 下午 mybatis.controller.Test main信息: 查询2结束第二次查询直接在缓存中获取,即一级缓存sqlSession十一月 10, 2017 9:58:06 下午 mybatis.controller.Test main信息: 开启第二个session开启另外一个sqlSession进行查询,再次打开一个连接,因为一级缓存中各个sqlSession是互相隔离的Opening JDBC ConnectionCreated connection 1182320432.Setting autocommit to false on JDBC Connection [com.mysql.jdbc.Connection@4678c730]==> Preparing: select bid, author, name, title, price, des from t_book where bid = ? ==> Parameters: 30(Integer)<== Columns: bid, author, name, title, price, des<== Row: 30, ww2, 大白菜2, 系统2, 2.50, 东风谷<== Total: 1Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.Connection@3a82f6ef]十一月 10, 2017 9:58:06 下午 mybatis.controller.Test main信息: 查询结束Closing JDBC Connection [com.mysql.jdbc.Connection@3a82f6ef]Returned connection 981661423 to pool.<== Columns: bid, author, name, title, price, des <== Row: 30, ww2, 大白菜2, 系统2, 2.50, 东风谷 <== Total: 1
2. 二级缓存
如要二级缓存,需要在SqlSessionFactory层面上开启,使得各个sqlSession对象可以共享。但是需要配置缓存和sqlSession提交,而且返回的POJO必须是可序列化的。
<cache/> //配置缓存,在对应实体类的映射配置文件中添加
public class Book implements Serializable //实体类可序列化
logger.info("开启第一个session"); session = sqlSessionFactory.openSession(); BookMapper bookMapper1 = session.getMapper(BookMapper.class); logger.info("同一个session查询1"); Book book = bookMapper1.findById(30); logger.info("同一个session查询2"); Book book1 = bookMapper1.findById(30); logger.info("查询2结束"); session.commit(); //开启二级缓存,sqlSession调用commit后才能生效 logger.info("开启第二个session"); SqlSession session2 = sqlSessionFactory.openSession(); BookMapper bookMapper2 = session2.getMapper(BookMapper.class); Book book2 = bookMapper2.findById(30); logger.info("查询结束"); session2.commit();
//开启二级缓存,sqlSession调用commit后才能生效
十一月 10, 2017 10:15:46 下午 mybatis.controller.Test main
信息: 开启第一个session
十一月 10, 2017 10:15:46 下午 mybatis.controller.Test main
信息: 同一个session查询1 //sqlSession第一次进行查询,创建连接、查询出结果并保存缓存
Cache Hit Ratio [mybatis.dao.BookMapper]: 0.0
Opening JDBC Connection
Created connection 1418370913.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.Connection@548a9f61]
==> Preparing: select bid, author, name, title, price, des from t_book where bid = ?
==> Parameters: 30(Integer)
<== Columns: bid, author, name, title, price, des
<== Row: 30, ww2, 大白菜2, 系统2, 2.50, 东风谷
<== Total: 1
十一月 10, 2017 10:15:47 下午 mybatis.controller.Test main
信息: 同一个session查询2 //第二次查询,依旧利用同一sqlSession中的缓存
十一月 10, 2017 10:15:47 下午 mybatis.controller.Test main
信息: 查询2结束
Cache Hit Ratio [mybatis.dao.BookMapper]: 0.0
十一月 10, 2017 10:15:47 下午 mybatis.controller.Test main
信息: 开启第二个session //新打开sqlSession,并没有重新创建连接进行查询,而是利用已有的缓存,即第一次sqlSession
十一月 10, 2017 10:15:47 下午 mybatis.controller.Test main
Cache Hit Ratio [mybatis.dao.BookMapper]: 0.3333333333333333
信息: 查询结束
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.Connection@548a9f61]
Closing JDBC Connection [com.mysql.jdbc.Connection@548a9f61]
Returned connection 1418370913 to pool.
3. 缓存Cache
<cache eviction="LRU" flushInterval="20000" size="1024" readOnly="true"/>
1.eviction:缓存回收策略
LRU,最近最少使用的,移除嘴上时间不用的对象
FIFO,先进先出,按对象缓存顺序来移除
SOFT,软引用,移除基于垃圾回收器状态和软引用规则的对象
WEAK,弱引用,更积极地移除基于垃圾收集器状态和弱引用规则的对象
2.flushInterval:刷新间隔时间单位毫秒,如果不配置则当sql执行的时候才会刷新缓存
3.size:引用数目,一个整数,代表缓存最多可存储的对象,一般不宜过大会导致内存溢出
4.readOnly:只读,则缓存的数据只能读取二不能修改,默认false