mybatis一级缓存二级缓存

一级缓存

在mybatis中是默认开启的,一级缓存是单个session级别的,只在一次会话中有效,一个SqlSession对象中创建一个本地缓存,对于每一次查询,都会尝试根据查询的条件去本地缓存中查找是否在缓存中,如果在缓存中,就直接从缓存中取出,然后返回;否则,从数据库读取数据,将查询结果存入缓存并返回。

一级缓存失效

  1. 会话结束,缓存失效。
  2. SqlSession调用了close(),会释放掉一级缓存PerpetualCache对象,一级缓存失效。
  3. SqlSession调用了clearCache(),会清除缓存PerpetualCache对象中的数据,缓存失效。
  4. SqlSession执行了任何一个update操作(update()、delete()、insert()) ,都会清空PerpetualCache对象的数据,但是该对象可以继续使用。

使用一级缓存

首先得确保俩次执行的sql语句是一致的。

此处多余代码不再赘述,只贴出关键代码。

@Resource
private SqlSessionFactory factory; 


public User selectById() {
    
   SqlSession sqlSession = factory.openSession();
   System.err.println("第一次执行");
   UserMapper userMapper1 = sqlSession.getMapper(UserMapper.class);
   System.err.println(userMapper1.selectByUserId(1).toString());

   System.err.println("第二次执行");
   UserMapper userMapper2 = sqlSession.getMapper(UserMapper.class);
   System.err.println(userMapper2.selectByUserId(1).toString());
}

执行结果如下

可以发现,sql只执行了一次,第二次并没有执行还是可以得到同样的user对象。那么此时这个session会话已经结束了,或许你会跟我有疑问谁会这样傻逼的这么写代码呢?我已经得到了userId为1的用户了,我在同一个方法里不可能再去写一遍查询id为1的用户。目前我资历尚欠,实际开发中也没有遇到这种一级缓存例子,所以这个实际应用还需要多方面看一下。

二级缓存

SqlSessionFactory层面上的二级缓存默认是不开启的,二级缓存的开启需要进行配置,实现二级缓存的时候,MyBatis要求返回的POJO必须是可序列化的。 也就是要求实现Serializable接口,配置方法很简单,只需要在映射XML文件配置就可以开启缓存了<cache/>,如果我们配置了二级缓存就意味着:

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

二级缓存开启

mybatis.configuration.cache-enabled=true
<mapper namespace="com.example.demo.mapper.UserMapper">
    <!--开启mybatis二级缓存-->
    <cache/>

    <resultMap id="BaseResultMap" type="com.example.demo.bean.User">
        <id column="id" property="id" />
        <result column="username" property="username" />
        <result column="password" property="password" />
    </resultMap>

    <select id="selectByUserId"   parameterType="int" resultMap="BaseResultMap">
        select * from user where id = #{id}
    </select>

</mapper>

使用二级缓存

@Resource
private UserMapper userMapper;

public User selectById() {
    System.err.println("第一次执行");
    System.err.println(userMapper.selectByUserId(1).toString());

    System.err.println("第二次执行");
    System.err.println(userMapper.selectByUserId(1).toString());

    return null;
}

这一次调用注入的mapper即可。

执行效果如下

可以看到创建了一个新的SqlSession,执行了一次sql,在不开启缓存的情况下,肯定是要执行俩次sql的。

再次执行

 

 此时已经不在和数据库发生交互,这样在实际项目就会大大减轻数据库的压力。

以上就是mybatis缓存。

加入我们群

如果有需要,欢迎可以加入我们的QQ群!(QQ搜索 1074281704,加入我们的QQ群吧!)
有任何问题,也可以加入我们的QQ群,欢迎交(che)流(dan)!也欢迎参观我的博客www.aquestian.cn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

答 案

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值