mybatis中的一级缓存和二级缓存(随笔记)

一级缓存

一级缓存是Sqlsession级别的缓存,再操作数据库时需要构造sqlsession对象,在对象中有一个内存区域 数据结构 hashMap 用于存储缓存数据。不同的sqlsession之间的缓存数据区域 hashmap互不影响。

mybatis默认开启一级缓存
一级缓存的作用域是同一个sqlsession,在同一个sqlsession中两次执行相同的sql语句,第一次执行完毕会将查询出的数据写到缓存中,第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率,当一个sqlsession结束后该sqlsession中的一级缓存也就不存在了。

public void testCache1() throws Exception{
      SqlSessionsqlSession = sqlSessionFactory.openSession();//创建代理对象
      UserMapperuserMapper = sqlSession.getMapper(UserMapper.class);

      //下边查询使用一个SqlSession

      //第一次发起请求,查询id为1的用户
      Useruser1 = userMapper.findUserById(1);
      System.out.println(user1);

//    如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。

      //更新user1的信息
      user1.setUsername("测试用户22");
      userMapper.updateUser(user1);

      //执行commit操作去清空缓存
      sqlSession.commit();

      //第二次发起请求,查询id为1的用户
      Useruser2 = userMapper.findUserById(1);
      System.out.println(user2);
     
      sqlSession.close();

如果不commit的错误流程为:

开始执行时,开启事务,创建SqlSession对象
第一次调用mapper的方法findUserById(1)
更新数据
第二次调用mapper的方法findUserById(1),从一级缓存中取数据
aop控制 只要方法结束,sqlSession关闭 sqlsession关闭后就销毁数据结构,清空缓存
Service结束sqlsession关闭

因为上面有commit操作,所以正确流程

开始执行时,开启事务,创建SqlSession对象
第一次调用mapper的方法findUserById(1)
更新数据
清空commit
第二次调用mapper的方法findUserById(1),从一级缓存中无数据,从数据库中取数据
aop控制 只要方法结束,sqlSession关闭 sqlsession关闭后就销毁数据结构,清空缓存
Service结束sqlsession关闭

只要是在同一个sqlsession中,一级缓存才会生效,如果sqlsession.commit() 或者 sqlsession.close()就会清空sqlsession,一级缓存也随之消失。

二级缓存

二级缓存是mapper级别的缓存,多个sqlsession去操作同一个mapper的sql语句,多个sqlsession去操作数据库得到数据会存在二级缓存区域,多个slqsession可以共同二级缓存,二级缓存是多个sqlsession共享的。

Usermapper有一个二级缓存区域 按照namespace分,如果namespace相同则使用同一个相同的二级缓存区,其它mapper也有自己依照namespace区分的二级缓存区域。也就是说拥有相同的namespace的Usermapper共享一个二级缓存

开启缓存
sqlMapConfig中

<setting name="cacheEnabled"value="true"/>

<!-- 全局配置参数,需要时再设置 -->
    <settings>
    <!-- 开启二级缓存  默认值为true -->
    <setting name="cacheEnabled" value="true"/>
    </settings>

在Usermapper.xml中开启二级缓存,UserMapper.xml下的执行完成会存储到它的缓存区域hashMap
下面是开启redis缓存

<mapper namespace="cn.mybatis.xml.mapper.UserMapper">
 
	<!-- redis配置项 -->
	<cache type="org.mybatis.caches.redis.RedisCache" /> 
    ...

redis与mybatis的整合:https://blog.csdn.net/magi1201/article/details/85635878

如何使用二级缓存

public class Userimplements Serializable {

    //Serializable实现序列化,为了将来反序列化
// 二级缓存测试

   @Test
   public void testCache2() throws Exception {
      SqlSessionsqlSession1 = sqlSessionFactory.openSession();
      SqlSessionsqlSession2 = sqlSessionFactory.openSession();
      SqlSessionsqlSession3 = sqlSessionFactory.openSession();
      
      // 创建代理对象
      UserMapperuserMapper1 = sqlSession1.getMapper(UserMapper.class);

      // 第一次发起请求,查询id为1的用户
      Useruser1 = userMapper1.findUserById(1);
      System.out.println(user1);

      //这里执行关闭操作,将sqlsession中的数据写到二级缓存区域
      sqlSession1.close();

      //使用sqlSession3执行commit()操作
      UserMapperuserMapper3 = sqlSession3.getMapper(UserMapper.class);
      Useruser  = userMapper3.findUserById(1);
      user.setUsername("张明明");
      userMapper3.updateUser(user);
      
      //执行提交,清空UserMapper下边的二级缓存
      sqlSession3.commit();
      sqlSession3.close();

      UserMapperuserMapper2 = sqlSession2.getMapper(UserMapper.class);
      
      // 第二次发起请求,查询id为1的用户
      Useruser2 = userMapper2.findUserById(1);
      System.out.println(user2);

      sqlSession2.close();

   }

执行结果:

sqlsession1中使用findUserById(1)
关闭sqlsession1
sqlsession3中使用findUserById(1),从缓存中取出数据
sqlSession3.commit();
sqlSession3.close()
sqlSession2中使用findUserById(1)无法拿到数据(commit刷新二级缓存)
sqlSession2.close()

原文地址:https://blog.csdn.net/qq_35688140/article/details/89848539

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值