• 第四章 MyBatis缓存和注解的使用


    1.MyBatis缓存的使用

            mybatis缓存分为一级缓存(针对一个sql会话)和二级缓存(针对不同的sql会话)

    1.1 一级缓存

            一级缓存默认开启,基于SqlSession级别的缓存,每一个SqlSession之间时相互独立的,当SqlSession执行:关闭、更新(增删改)、清空缓存操作时,会清空缓存。

    1.1.1 一级缓存原理

            MyBatis 对缓存提供支持,在默认没有配置的情况下,只开启一级缓存,一级缓存只对同一个SqlSession;只有在查询参数和SQL完全一样的情况下,使用同一个SqlSession对象调用同一个Mapper方法,只会执行一次SQL;在第一次查询后,MyBatis会将其查询结果放入缓存,如果没有声明刷新缓存或者缓存没有超时时,sqlSession会直接取出当前缓存的数据,而不会再次发送Sql到数据库。

    ①只执行了一次sql查询:

     ②清理缓存之后,两次sql查询:

     1.1.2 一级缓存的不足

            一级缓存不能跨会话,不同会话之间对于相同的数据可能有不一样的缓存;在有多个会话或者分布式环境下,会存在脏数据的问题,要解决这个问题,需要使用二级缓存。

    1.2 二级缓存 

            MyBatis的二级缓存是Application级别的缓存(对应namespace),可以提高对数据库查询的效率,以提高应用的性能。

            SqlSessionFactory 层面上的二级缓存默认不开启,开启二级缓存需要进行相应的配置;实现二级缓存时,MyBatis要求返回的POJO必须是可序列化的,就是要实现Serializable接口。

    配置二级缓存后:

    ①映射语句文件中所有的select语句将被缓存; 

    ②映射语句文件中的insert,update和delete语句会刷新缓存;

    ③缓存会使用默认的Least Recently Used(LRU,最近最少使用)算法回收;

    ④根据时间表,如 No Flush Interval(NFI 没有刷新间隔),缓存不会以任何时间顺序来刷新;

    ⑤缓存会存储列表集合或对象(无论查询方法返回什么)的1024个引用;

    ⑥缓存会被视为是read/write的缓存,表示对象检索不是共享的,而且可以安全的被调用者修改,不干扰其他调用者或线程所做的潜在修改。

    1.2.1  开启二级缓存的步骤

    ①实体对象实现序列化:

    1. @Data
    2. public class Goods implements Serializable {
    3. private Integer goodsId;
    4. private String goodsName;
    5. private Double price;
    6. private Date produceDate;
    7. private String address;
    8. private Category category;
    9. }

    ②在主配置文件中设置启用二级缓存:

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

    ③在需要使用缓存的mapper文件中配置cache标签,默认对当前mapper所有的查询方法生效;

    1. <mapper namespace="com.mapper.GoodsMapper">
    2. <cache eviction="LRU" flushInterval="1000" readOnly="true" size="1024"/>

    evication:缓存回收策略

            ①LRU,最近最少使用的,删除最长时间不用的;

            ②FIFO,先进先出,按对象进入缓存的顺序来移除他们;

            ③SOFT,软引用,移除基于垃圾回收器状态和软引用规则的对象;

            ④WEAK,弱引用,更积极的移除基于垃圾回收器状态和弱引用规则的对象。

    flushInterval:刷新间隔时间,单位为毫秒,不配置就是当sql被执行时才刷新

    size:引用数目,一个正整数,代表缓存最多可以存储多少个对象,设置过大会导致内存溢出

    readonly:只读,可以快速的读取缓存,但没办法修改缓存,默认为false。

    ④在某个查询方法上可以通过useCache单独配置是否启用缓存,默认启用

    1. <select id="goodsList" resultMap="goodsMap" useCache="true">
    2. select
    3. <include refid="colSql">include>
    4. from goods g join category c
    5. on g.category_id = c.category_id
    6. select>

     1.2.2 二级缓存原理

            二级缓存是用来解决一级缓存不能跨会话共享的问题,范围是 namespace 级别的,可以被多个 SqlSession 共享(是同一个接口的相同方法);配置了二级缓存之后,在执行select查询的时候,MyBatis会先从二级缓存中取数据,其次才是一级缓存,故 查询顺序是:二级缓存---->一级缓存 ----> 数据库

    1.2.3 演示效果

     注:二级缓存不能和延迟加载一起使用。

    2. MyBatis 注解

            除了 xml 配置映射对象外,也可以通过注解配置。

    简单注解有:

    @Insert   @Update    @Delete    @Select 

     2.1 简单查询

    1. public interface ClassInfoMapper {
    2. @Select("select * from class")
    3. List studentList();
    4. @Insert("insert into class(name) value (#{name})")
    5. int insert(Class c);
    6. @Update("update class set name = #{name} where id = #{id}")
    7. int update(Class c);
    8. @Delete("delete from class where id = #{id}")
    9. int delete(Integer id);
    10. }

    2.2 两表关联查询: 

    1. public interface StudentMapper {
    2. @Select("select * from stu")
    3. @Results(
    4. @Result(
    5. property = "classInfo",
    6. column = "clsId",
    7. one = @One(select = "com.mapper.ClassInfoMapper.classList")
    8. ))
    9. List studentList();
    10. }
    1. public interface ClassInfoMapper {
    2. @Select("select * from classinfo where class_id = #{id}")
    3. List classList();
    4. }

  • 相关阅读:
    你需要知道的13个有用的Python片段
    每日一题 146. LRU 缓存
    python-opencv学习笔记1 opencv中的GUI特征
    如何设置 Git 短命令
    java日常开发必备:list的四种遍历
    JAVA练习百题之求矩阵对角线之和
    低功耗窗帘电机解决方案成功应用并通过 Matter 1.1 认证
    flutter,javascript forEach await无效
    使用watch和tail命令监控文件内容的变化
    C++ 丑数
  • 原文地址:https://blog.csdn.net/m0_71674778/article/details/126387086