分享

mysql缓存:一级缓存和二级缓存

 Levy_X 2018-09-26

一级缓存:

  也称本地缓存,sqlSession级别的缓存。一级缓存是一直开启的;与数据库同一次回话期间查询到的数据会放在本地缓存中。

  如果需要获取相同的数据,直接从缓存中拿,不会再查数据库。

  一级缓存失效的四种情况:

    1.sqlSession不同。

      eg:

1
2
3
@Test
    public void test01() throws IOException {
        SqlSessionFactory sqlSessionFactry = getSqlSessionFactory(); <br>          SqlSession session = sqlSessionFactory.openSession();<br>          EmployeeMapper mapper = session.getMapper(EmployeeMapper.class); <br>          try { Employee map = mapper.getEmployeeById(1);<br>             Employee map2 = mapper.getEmployeeById(1);<br>          System.out.println(map == map2);<br>                session.commit(); <br>               } <br>               finally { session.close(); } <br>        } <br>输出结果为true 数据库只查询一次,map2取缓存结果

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Test
    public void test01() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
         SqlSession session = sqlSessionFactory.openSession();
                 SqlSession session2 = sqlSessionFactory.openSession();
         EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
                 EmployeeMapper mapper2 = session.getMapper(EmployeeMapper.class);
         try {
             Employee map  = mapper.getEmployeeById(1);
                         Employee map2  = mapper.getEmployeeById(1);
             System.out.println(map == map2);
             session.commit();
            } finally {
                session.close();
            }
    }
输出结果为false
两个不同的sqlSession

      2.sqlSession相同,查询条件不同。因为缓存条件不同,缓存中还没有数据。

      3.sqlSession相同,在两次相同查询条件中间执行过增删改操作。(因为中间的增删改可能对缓存中数据进行修改,所以不能用)

      4.sqlSession相同,手动清空了一级缓存。

        eg:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Test
    public void test01() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
         SqlSession session = sqlSessionFactory.openSession();
         EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
         try {
             Employee map  = mapper.getEmployeeById(1);
                         session.clearCache();
                         Employee map2  = mapper.getEmployeeById(1);
             System.out.println(map == map2);
             session.commit();
            } finally {
                session.close();
            }
    }
输出结果为false.
因为手动清清除缓存,缓存失效

  二级缓存:全局缓存;基于namespace级别的缓存。一个namespace对应一个二级缓存。

      工作机制:1.一个会话,查询一条数据,这个数据会被放在当前会话的一级缓存中。

           2,如果会话被关闭了,一级缓存中的数据会被保存带二级缓存。新的会话查询信息就会参照二级缓存。

           3.sqlSession ====> Employee====>employee

            sqlSession ====>DepartmentMapper=====>Department

            不同的namespace查出的数据会放在自己对应的缓存中。

           效果:查出的数据首先放在一级缓存中,只有一级缓存被关闭或者提交以后,一级缓存数据才会转移到二级缓存

         使用步骤:

            1.开启全局缓存配置。<settings><setting name='cacheEnabled' value='true'/></settings>

            2.因为是namespace级别,需要搭配每个xxxMapper.xml中配置二级缓存<cache></cache>

             <cache flushInterval='60000' size='512' readOnly='true' eviction='FIFO' type='' />

              eviction:缓存的回收策略:

                     LRU – 最近最少使用的:移除最长时间不被使用的对象。

                     FIFO – 先进先出:按对象进入缓存的顺序来移除它们。

                     SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。

                     WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

              flushInterval:缓存刷新间隔。缓存多久清空一次,默认不清空。设置一个毫秒值。

              readOnly:是否只读。true:mybatis认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。

                             mybatis为了加快获取速度,直接就会将数据在缓存中的引用交给用户。不安全,速度快。

                        false:mybatis觉得获取的数据可能被修改。mybatis会利用序列化和反序列化的技术克隆一份新的数据给用户。安全,速度快。

              size:缓存放多少元素。

              type:指定自定义缓存全类名。实现cache接口即可。

              3.pojo需要实现序列换接口。

        和缓存相关的配置/属性:

              1.cacheEnabled:如果是false,关闭二级缓存,不关闭一级缓存。

              2.每个select标签都有userCache='true'属性:对一级缓存没有影响。设置为false,二级缓存失效。

              3.每个增删改标签都有flushCache='true'属性:一级缓存和二级缓存都会被清空。

              4.在查询标签中flushCache='false'属性:如果设置为true,查完会清空,一级二级缓存都会被清空,都不会用缓存。

              5.sqlSession.clearn():跟session有关,只会清除一级缓存。

              6.localCacheScope:<settings><setting name='localCacheScope' value='SESSION'/></settings>本地缓存作用域。

                        一级缓存SESSION:当前会话的所有数据保存到回话缓存中。STATEMENT:禁用一级缓存。

 

缓存首先一进来去查二级缓存,二级缓存没有去找一级缓存,一级缓存没有去找数据库。二级缓存----->一级缓存-------->数据库。

自定义缓存 implements Cache,重写接口中的保存等方法,比如说保存到redis.

自定义缓存参照mybatis官网--->项目git代码库----->https://github.com/mybatis---->参照各种整合缓存

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多