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)不推荐使用

 

posted @ 2020-06-06 19:22  守林鸟  阅读(184)  评论(0编辑  收藏  举报