课时10:MyBatis一级缓存二级缓存

Posted 何邦柱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了课时10:MyBatis一级缓存二级缓存相关的知识,希望对你有一定的参考价值。

.1)查询缓存

  1.一级缓存

    1.1 同一个SqlSession对象,mybatis默认就开启了一级缓存,下方为示意图

    1.2 如果用同样的SqlSession对象查询相同的数据,则只会在第一次 查询时 向数据库发送SQL语句,并将查询的结果 放入SqlSession中(作为缓存存在);后续再次查询同样的对象时,则直接从缓存中查询该对象即可(则省略了数据库的访问)

    1.3 一旦commit就会清空SqlSession中的缓存

    1.4测试代码如下

 public static void selectOneStudent() throws IOException {
        Reader reader = Resources.getResourceAsReader("config.xml");
        SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(reader);
        SqlSession session=sessionFactory.openSession();
        IStudentDao iStudentDao=session.getMapper(IStudentDao.class);
        Student student = iStudentDao.selectStudentById(1);
        session.commit();
        Student student2 = iStudentDao.selectStudentById(1);
        System.out.println(student);
        System.out.println(student2);
        session.close();
        reader.close();
    }

  2.二级缓存

    2.1 mybatis默认关闭二级缓存 需要手动的打开

      2.1.1 在主配置文件中配置

<!--        开启二级缓存-->
        <setting name="cacheEnabled" value="true"/>

      2.1.2 在具体的mapper.xml声明开启

<!--    声明开启-->
<cache/>

      2.1.3 异常提示 :java.io.NotSerializableExceptio可知,mybatis的二级缓存是将对象 放入硬盘

        序列化:内存---》硬盘

        反序列化:硬盘---》内存

        如何解决?

         在实体类中实现Serializable接口 (序列化student类,以及Student的级联属性,和Student父类)

    2.2  二级缓存的范围在同一个namespace中产生的接口生成的代理对象都可以共享缓存

 

       2.3 如果是同一个SqlSession对象进行多次查询,则直接进入一级缓存查询; 如果不是同一个SqlSession进行多次查询(但是都是一个namespace),则进入二级缓存

    2.4 测试如下:

 public static void selectOneStudent() throws IOException {
        Reader reader = Resources.getResourceAsReader("config.xml");
        SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(reader);
        SqlSession session=sessionFactory.openSession();
        IStudentDao iStudentDao=session.getMapper(IStudentDao.class);
        Student student = iStudentDao.selectStudentById(1);
        SqlSession session2=sessionFactory.openSession();
        IStudentDao iStudentDao2=session2.getMapper(IStudentDao.class);
        Student student2 = iStudentDao2.selectStudentById(1);
        System.out.println(student);
        System.out.println(student2);
        session.close();
        reader.close();
    }

    2.5 细节补充在查询完一次之后需要关闭SqlSession,不然该对象不会存入二级缓存

      存储时机就是当执行SqlSession.close()时 才会存入到二级缓存,

      如果多个文件的namespace的值相同,通过这些mapper.xml产生的mapper对象 仍然共享二级缓存

 

以上是关于课时10:MyBatis一级缓存二级缓存的主要内容,如果未能解决你的问题,请参考以下文章

一级缓存和二级缓存有啥区别

课时11:禁用清理二级缓存,以及整合Ehcache缓存

什么是缓存?一级缓存?二级缓存?

谁给我解释一下一级缓存和二级缓存啊~

一级数据缓存,一级指令缓存和二级缓存有啥区别?

MyBatis缓存看这一篇就够了(一级缓存+二级缓存+缓存失效+缓存配置+工作模式+测试)