继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

MyBatis3.2.x从入门到精通之第九章(二级缓存)

HansonQ
关注TA
已关注
手记 21
粉丝 334
获赞 3452
  1. 二级缓存原理:
    二级缓存原理图
    二级缓存区域是根据mapper的namespace划分的,相同namespace的mapper查询数据放在同一个区域,如果使用mapper代理方法每个mapper的namespace都不同,此时可以理解为二级缓存区域是根据mapper划分。
    每次查询会先从缓存区域找,如果找不到从数据库查询,查询到数据将数据写入缓存。
    Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象
    sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。
  2. 开启二级缓存
    在核心配置文件SqlMapConfig.xml中加入
    <setting name="cacheEnabled" value="true"/>
    说明:cacheEnabled 对在此配置文件下的所有cache 进行全局性开/关设置。 默认值true
    要在你的Mapper映射文件中添加一行: <cache /> ,表示此mapper开启二级缓存。
  3. 实现序列化
    二级缓存需要查询结果映射的pojo对象实现java.io.Serializable接口实现序列化和反序列化操作,注意如果存在父类、成员pojo都需要实现序列化接口。
    public class Orders implements Serializable
    public class User implements Serializable
  4. 测试
//获取session1
        SqlSession session1 = sqlSessionFactory.openSession();
        UserMapper userMapper = session1.getMapper(UserMapper.class);
        //使用session1执行第一次查询
        User user1 = userMapper.findUserById(1);
        System.out.println(user1);
        //关闭session1
        session1.close();
        //获取session2
        SqlSession session2 = sqlSessionFactory.openSession();
        UserMapper userMapper2 = session2.getMapper(UserMapper.class);
        //使用session2执行第二次查询,由于开启了二级缓存这里从缓存中获取数据不再向数据库发出sql
        User user2 = userMapper2.findUserById(1);
        System.out.println(user2);
        //关闭session2
        session2.close();
  1. 禁用二级缓存
    在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。
    <select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">
  2. 刷新缓存
    在mapper的同一个namespace中,如果有其它insert、update、delete操作数据后需要刷新缓存,如果不执行刷新缓存会出现脏读。
    设置statement配置中的flushCache="true" 属性,默认情况下为true即刷新缓存,如果改成false则不会刷新。使用缓存时如果手动修改数据库表中的查询数据会出现脏读。
    如下:
    <insert id="insertUser" parameterType="cn.hanson.mybatis.po.User" flushCache="true">
  3. Mybatis Cache参数
    flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
    size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是1024。
    readOnly(只读)属性可以被设置为true或false。只读的缓存会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。
    如下例子:
    <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
    这个更高级的配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会导致冲突。可用的收回策略有, 默认的是 LRU:
    1. LRU – 最近最少使用的:移除最长时间不被使用的对象。
    2. FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
    3. SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
    4. WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
      当然了mybatis是可以和其他的缓存框架整合的。这里需要大家去多多了解了。
打开App,阅读手记
15人推荐
发表评论
随时随地看视频慕课网APP

热门评论

为什么我不管开不开启二级缓存,第二遍查询都很快呢?哪怕useCache="false"也一样。

第一遍查询后session1关闭,再用session2进行第二遍查询,非常快。

刚刚发现哪怕第二遍查询的是别的UserId也一样速度非常快。

楼主,这两天也不断问你问题,多谢哈,也跟上更新的步伐了,接下来还有没有mybatis的更新?

想学好还是很难的...

查看全部评论