所谓的缓存呢?其实原理很简单,就是在保证你查询的数据是正确的情况下,没有去查数据库,而是直接查找的内存,这样做有利于缓解数据库的压力,提高数据库的性能,Mybatis中有提供一级缓存和二级缓存。

  学习一级缓存和二级缓存之前先来看一张缓存的原理图:

  

  分析一个这个图:(从这个图中我们大概可以看出一下几点)

    1.回顾一下SqlSession是操作数据库的会话。

    2.一级缓存是对单个SqlSession而言的,无法跨SqlSession。

    3.二级缓存是对namespace而言的,可以跨SqlSession。

    4.二级缓存的范围比一级缓存大。

    5.一级缓存是默认开启的,二级缓存要手动开启的。

  使用缓存的时候大家应该会产生一个疑问,就是使用缓存的时候,读取数据会不会准确,是否会出现都脏数据的情况。

  接下来我们先来看一下一级缓存:

    一级缓存的原理图:

    

    分析:

      第一次发起查询请求的时候由于缓存没有数据,会去查询数据库。

      第二次发起查询请求的时候缓存中有数据,就会从缓存中查询数据。

      注意:查询缓存这里有两个前提:

        第一个是:查询条件不变

        第二个是:没有执行增加,插入,更新带有commit操作的,只要有执行关于commit操作的就会清空缓存

      一级缓存是默认开启的,不需要设置

   二级缓存原理图:

    

    看这个图,大家就会知道,二级缓存和一级缓存的原理是类似的,唯一不同的是二级缓存需要配置,并且是跨SqlSession的。

    分析一下一级缓存和二级缓存的区别:

      一级缓存和二级缓存的区别:

        二级缓存的范围比一级缓存大。

        二级缓存可以多个sqlsession共享。

        Commit的时候不管是一级缓存还是二级缓存都会清空

      二级缓存的一个划分:

        按照namespace来划分的 ,就是每一个namespace都要自己的一个二级缓存区域。

    开启二级缓存:

      1.全局配置文件中配置 (SqlMapConfig.xml)

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

 

      2.mapper中配置   

<!-- 开启二级缓存 -->
<cache></cache>

 

    测试二级缓存:(测试的原理其实和简单,既然二级缓存是跨SqlSession的,你就开启多个SqlSession,同样的查询条件,看看会不会走缓存就OK了)

    @Test
    public void cachetwo() throws IOException{
        //mybatis的配置文件
        String resource="mybatis-config.xml";
        //得到配置文件流
        InputStream inputStream= Resources.getResourceAsStream(resource);
        //创建会话工厂,需要传入Mybatis的配置文件信息
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //通过工厂得到SqlSession
        SqlSession session=sessionFactory.openSession();
        SqlSession session2=sessionFactory.openSession();
        SqlSession session3=sessionFactory.openSession();
        //创建StudentMapper对象,mybatis自动生成代理对象
        StudentMapper studentMapper=session.getMapper(StudentMapper.class);
        List<Student>list=studentMapper.findAll();
        session.close();
        StudentMapper studentMapper2=session2.getMapper(StudentMapper.class);
        List<Student>list1=studentMapper.findAll();
        session2.close();
        //资源释放    
    }