mybatis缓存机制

本文详细介绍了MyBatis的一级和二级缓存机制。一级缓存默认启用,存在于SqlSession生命周期中,同一SqlSession内相同查询仅执行一次。二级缓存则跨SqlSession,以namespace为单位,需要手动配置开启,所有数据被缓存为原始值而非对象。当执行增删改操作时,相应级别缓存会被清空。
摘要由CSDN通过智能技术生成

 1、一级缓存

MyBatis 包含一个非常强大的查询缓存特性,使用缓存可以使应用更快地获取数据,避免频繁的数据库交互 ;

  •  一级缓存默认会启用,想要关闭一级缓存可以在select标签上配置flushCache=“true”;
  •  一级缓存存在于 SqlSession 的生命周期中,在同一个 SqlSession 中查询时, MyBatis 会把执行的方法和 参数通过算法生成缓存的键值,将键值和查询结果存入一个 Map对象中。如果同一个 SqlSession 中执行的 方法和参数完全一致,那么通过算法会生成相同的键值,当 Map 缓存对象中己经存在该键值时,则会返回缓存中的对象;
  •  任何的 INSERT 、UPDATE 、 DELETE 操作都会清空一级缓存;

一级缓存为一级缓存是SqlSession级别的缓存,只要当前SqlSession没有commit或close,它就存在,当然当前SqlSession对数据库执行增删改操作时,一级缓存也会相应清空。一级缓存与生俱来,默认即开启并使用。

public static void main(String[] args) {
        // 自定义的单例SqlSessionFactory模式
        SqlSessionFactory factory = SqlSessionFactoryUtil.openSqlSession();

        // 获得SqlSession对象
        SqlSession sqlSession = factory.openSession();
        // 获得dao实体
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        // 进行两次相同的查询操作
        userMapper.selectByPrimaryKey(1);
        userMapper.selectByPrimaryKey(1);
        // 注意,当我们使用二级缓存时候,sqlSession需要使用commit时候才会生效
        sqlSession.commit();

        System.out.println("\n\n=============================================================");
        // 获得一个新的SqlSession 对象
        SqlSession sqlSession1 = factory.openSession();
        // 进行相同的查询操作
        sqlSession1.getMapper(UserMapper.class).selectByPrimaryKey(1);
        // 注意,当我们使用二级缓存时候,sqlSession需要使用commit时候才会生效
        sqlSession.commit();
    }

日志输出

DEBUG [main] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@77caeb3e]
DEBUG [main] - ==>  Preparing: select user_ID, login_name,user_name, user_code, user_type, user_active, organization_ID,user_position,password from user where user_ID = ? 
DEBUG [main] - ==> Parameters: 1(Integer)
TRACE [main] - <==    Columns: user_ID, login_name, user_name, user_code, user_type, user_active, organization_ID, user_position, password
TRACE [main] - <==        Row: 1, ASH-001, 小明, JIKF-001, ADMIN, 1, 0, 销售员, 1212121212121
DEBUG [main] - <==      Total: 1


=============================================================
DEBUG [main] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@553f17c]
DEBUG [main] - ==>  Preparing: select user_ID, login_name,user_name, user_code, user_type, user_active, organization_ID,user_position,password from user where user_ID = ? 
DEBUG [main] - ==> Parameters: 1(Integer)
TRACE [main] - <==    Columns: user_ID, login_name, user_name, user_code, user_type, user_active, organization_ID, user_position, password
TRACE [main] - <==         Row: 1, ASH-001, 小明, JIKF-001, ADMIN, 1, 0, 销售员, 1212121212121
DEBUG [main] - <==      Total: 1

可以发现,第一次的两个相同操作,只执行了一次数据库。后来的那个操作又进行了数据库查询。

2、二级缓存

  • 二级缓存存在于 SqlSessionFactory 的生命周期中,可以理解为跨sqlSession;缓存是以namespace为单位的,不同namespace下的操作互不影响。
  • setting参数 cacheEnabled,这个参数是二级缓存的全局开关,默认值是 true,如果把这个参数设置为 false,即使有后面的二级缓存配置,也不会生效;
  • 要开启二级缓存,你需要在你的 SQL 映射文件中添加配置:
    <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>  

 默认二级缓存是不开启的,需要手动进行配置。在映射文件中;

<cache/>

如果这样配置的话,很多其他的配置就会被默认进行,如:

  • 映射文件所有的select 语句会被缓存
  • 映射文件的所有的insert、update和delete语句会刷新缓存
  • 缓存会使用默认的Least Recently Used(LRU,最近最少使用原则)的算法来回收缓存空间
  • 根据时间表,比如No Flush Interval,(CNFI,没有刷新间隔),缓存不会以任何时间顺序来刷新
  • 缓存会存储列表集合或对象(无论查询方法返回什么)的1024个引用
  • 缓存会被视为是read/write(可读/可写)的缓存,意味着对象检索不是共享的,而且可以很安全的被调用者修改,不干扰其他调用者或县城所作的潜在修改。

添加后日志打印如下,可以发现所有过程只使用了一次数据库查询:

EBUG [main] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@5622fdf]
DEBUG [main] - ==>  Preparing: select user_ID, login_name,user_name, user_code, user_type, user_active, organization_ID,user_position,password from user where user_ID = ? 
DEBUG [main] - ==> Parameters: 1(Integer)
TRACE [main] - <==    Columns: user_ID, login_name, user_name, user_code, user_type, user_active, organization_ID, user_position, password
TRACE [main] - <==        Row: 1, AS-01, 小明, HJ-009, ADMIN, 1, 0, 销售员, dasfasdfasdfsdf
DEBUG [main] - <==      Total: 1


=============================================================

通过<cache-ref>“...”</chcha-ref>可使多个mapper共享一个二级缓存。

二级缓存有几个特点:

  • 1.缓存的是数据,而不是对象(这一点与一级缓存不同),需要注意。
  • 2.二级缓存在sqlsession执行commit()方法后才会被写入。
  • 3.不同的sqlsession执行增删改方法,只要操作的是同一个mapper就会清空二级缓存区域。
  • 4.查询数据时,优先从二级缓存区获取数据,如果二级缓存区没有数据,才会找一级缓存区。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值