zoukankan      html  css  js  c++  java
  • 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)不推荐使用

  • 相关阅读:
    mysql使用笔记
    js this指向练习题
    for in 和for of的区别
    ES6 Iterator(迭代器或遍历器)和 Generator (生成器)
    vue兄弟之间传值 bus中央事件总线
    关于recycleview 滑动item变长(item变形)问题
    蓝牙篇
    如何限制应用安装,
    网络工具,通过该类可以直接监听网络状态改变
    MyRecycleView带有上拉加载更多
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/13051261.html
Copyright © 2011-2022 走看看