Mybatis_4_一二级缓存机制

1.缓存机制简介

1)缓存可以极大提升查询的效率

2)Mybatis系统默认定义了两级缓存

一级缓存

二级缓存

3)默认情况下,只有一级缓存开启

4)二级缓存呢需要手动开启和配置,它是基于namespace级别的缓存

5)为了提高扩展性,Mybatis定义了缓存借口Cache。我们可以通过实现Cache接口来自定义二级缓存。

 

2.一级缓存的使用

1)一级缓存(local cache)即本地缓存,作用域默认为sqlSession。当Session flush或者close后,该Session中的所有Cahe将被清空。

2)本地缓存不能被关闭,不能被关闭,但可以调用clearChche()来清空本地缓存,或者改变缓存的作用域。

3)一级缓存的工作机制:

同一次SqlSession期间,只要查询国的数据都会保存在当前SqlSession的一个Map中:

key:hashCode+查询的SqlId+编写的sql查询语句+参数

4)一级缓存的失效的几种情况:

不同的SqlSession对应不同的一级缓存

同一个SqlSession但查询条件不同

同一个SqlSession两次查询期间执行了增删改操作

同一个SqlSession两次查询之间手动清空了缓存

 

3.二级缓存的使用

1)二级缓存为全局作用缓存

2)二级缓存默认不开启,需要手动配置

3)Mybatis提供二级缓存的接口及实现,要求相关POJO必须实现serializable接口

4)二级缓存在SqlSession关闭或提交之后才会生效

5)二级缓存使用的步骤:

S1 全局配置文件中开启二级缓存<setting name="cacheEnabled" value="true"/>

S2 需要使用二级缓存的映射文件处使用cache配置缓存<cache />

S3 注意:POJO需要实现Serializable接口

6)二级缓存相关的属性

  • 缓存回收策略: LRU-最近最少使用;FIFO:先进先出
  • flushInterval:刷新间隔,单位毫秒,默认永不刷新
  • size:引用数目,代表缓存最多可以存储多少个对象,太大容易导致内存溢出
  • readOnly:只读,rue/falss.

  true:只读缓存,会给所有调用者返回对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。

  false:读写缓存,会给调用者返回对象的拷贝(通过序列化)。因此速度较慢,但是可以修改。默认为false。

实例代码:

@Test
    public void testSecondLevelCache() throws IOException {
        InputStream resource = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resource);
        SqlSession sqlSession1 = sqlSessionFactory.openSession();
        UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
        List<User> allUser1 = mapper1.getAllUser();
        System.out.println(allUser1.get(0));
        sqlSession1.commit();
        //在另一个sqlSession下完成查询
        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
        List<User> allUser2 = mapper2.getAllUser();
        System.out.println(allUser2.get(0));

        //在第三个sqlSession下完成查询
        SqlSession sqlSession3 = sqlSessionFactory.openSession();
        UserMapper mapper3 = sqlSession3.getMapper(UserMapper.class);
        List<User> allUser3 = mapper3.getAllUser();
        System.out.println(allUser3.get(0));
       
    }

输出结果:

DEBUG [main] (LoggingCache.java:62) - Cache Hit Ratio [com.mapper.UserMapper]: 0.0
DEBUG [main] (JdbcTransaction.java:136) - Opening JDBC Connection
DEBUG [main] (PooledDataSource.java:405) - Created connection 1662912171.
DEBUG [main] (JdbcTransaction.java:100) - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@631e06ab]
DEBUG [main] (BaseJdbcLogger.java:159) - ==>  Preparing: select id,username,upassword,email from t_user 
DEBUG [main] (BaseJdbcLogger.java:159) - ==> Parameters: 
DEBUG [main] (BaseJdbcLogger.java:159) - <==      Total: 11
User{id=1, username='admin', upassword='ad111', email='zhaofeixiang@cdut.edu.cn', dept=null}
DEBUG [main] (LoggingCache.java:62) - Cache Hit Ratio [com.mapper.UserMapper]: 0.5
User{id=1, username='admin', upassword='ad111', email='zhaofeixiang@cdut.edu.cn', dept=null}
DEBUG [main] (LoggingCache.java:62) - Cache Hit Ratio [com.mapper.UserMapper]: 0.6666666666666666
User{id=1, username='admin', upassword='ad111', email='zhaofeixiang@cdut.edu.cn', dept=null}

 4.缓存的相关属性

1)全局setting的cacheEnable:配置二级缓存的开关,一级缓存一直打开。

2)select标签的useCache属性:配置这个select标签是否使用二级缓存,默认true。

3)sql标签的flushCache属性:增删改默认flushCache=true。sql执行以后,会同时清空一级和二级缓存。查询默认flushCache=false。

4)sqlSession.clearCache():只用来清除一级缓存。

posted @ 2020-09-15 11:09  日进一卒  阅读(250)  评论(0)    收藏  举报