MyBatis(六)——缓存
1.概念
查过的东西存起来,下次直接拿。
2.一级缓存
本地缓存,是默认级别的缓存,作用域为sqlSession,当Session flush或者close之后,缓存消失。不可被关闭,可以调用clearCache()来清空本地缓存。
(1)工作机制
同一次会话期间只要查询过的数据都会保存在当前SqlSession的一个Map中。key=hashCode+查询的SqlId+编写的sql查询语句+参数。对于某个查询,先看看该key有木有数据,有就拿,没有就查。
(2)失效情况
不同SqlSession对应不同的一级缓存。
同一个SqlSession但查询条件不同。
同一个SqlSession两次相同查询之间,发生了增删改操作 或者 手动清空了缓存。
3.二级缓存
范围是namespace级别的,即整个Mapper,不同的SqlSession之间可以互取缓存。默认不开启,需要手动打开。
(1)POJO类需要实现接口Serializable
(2)在mybatis-config.xml里配置<settings>的子元素
<setting name="cacheEnabled" value="true"/>。
(3)在Mapper添加<cache/>标签。
- 回收策略eviction,LRU表示最少策略;FIFO表示先进先出;SOFT表示软引用,基于垃圾回收器状态和软引用规则移除对象;WEAK表示弱引用,更积极地基于垃圾收集器状态和弱引用规则移除对象。
- 刷新间隔flushInterval,单位毫秒,默认情况是不设置。
- 缓存数量size。
- 只读属性readOnly,true表示会给所有调用者返回缓存对象的相同实例,因此这些对象不能被修改,快;默认是false,慢但安全。
(4)<select>标签中的useCache属性表示是否开启二级缓存,如果上面的配完了,这里不配也行,如果配为false会使得方法的二级缓存失效。
(5)疑惑点
sqlSession手动提交或者关闭才能使得二级缓存生效。对于sessionFactory.openSession(true)创建出来的sqlSession虽然是默认提交的,但是不手动提交依旧不会有二级缓存。(不理解这个问题,如果有大佬知道,希望能帮忙解惑)
public static void main(String args[]) throws IOException { InputStream is=Resources.getResourceAsStream("mybatis-config.xml");//读取配置文件 SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(is);//构建工厂 SqlSession sqlSession=sessionFactory.openSession(true);//true表示自动提交 SqlSession sqlSession2=sessionFactory.openSession(true);//true表示自动提交 CustomerMapper mapper=sqlSession.getMapper(CustomerMapper.class); CustomerMapper mapper2=sqlSession2.getMapper(CustomerMapper.class); Customer customer=new Customer(); customer.setUsername("司马懿"); customer.setJobs("刺客"); customer.setPhone("129"); mapper.insertCustomer(customer); Map<String, Object> map=new HashMap<String, Object>(); map.put("id",2); System.out.println(mapper.selectById(map)); //sqlSession.close(); //sqlSession.commit();//在这里尝试修改 System.out.println("facai1"); System.out.println(mapper2.selectById(map)); System.out.println("facai2"); System.out.println(mapper2.selectById(map)); sqlSession.close();//关闭 }
(6)不推荐使用