MyBatis延迟加载、缓存机制与注解开发

一、延迟加载策略

1.1 延迟加载的概念

立即加载:查询用户时,默认也把该用户的所有账户信息查询出来

延迟加载:查询用户时,不查询账户信息,等需要使用账户数据时才去查询

1.2 应用场景

查询账户(多对一)时,可以直接查询用户信息 → 立即加载

查询用户(一对多)时,可以先不查账户信息 → 延迟加载

1.3 多对一延迟加载配置

在 SqlMapConfig.xml 中开启延迟加载:

复制代码
<settings>
    <!-- 开启延迟加载 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 将积极加载改为按需加载 -->
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>

AccountMapper.xml 配置:

复制代码
<resultMap id="accountMap" type="Account">
    <result property="id" column="id"/>
    <result property="uid" column="uid"/>
    <result property="money" column="money"/>
    <association property="user" javaType="User" 
                 select="com.qcbyjy.mapper.UserMapper.findById" 
                 column="uid"/>
</resultMap>

<select id="findAll" resultMap="accountMap">
    SELECT * from account
</select>

二、MyBatis缓存机制

2.1 一级缓存(SqlSession缓存)

一级缓存是 SqlSession 级别的缓存,底层使用Map集合存储:

key:执行的SQL语句

value:查询的结果对象

一级缓存的生命周期与SqlSession相同。以下操作会清空一级缓存:

session.clearCache()

session.update()、insert()、delete()、commit()、close()

复制代码
@Test
public void testFindById() {
    User user = mapper.findById(41);
    System.out.println(user);
    // 第二次查询会从缓存中获取,不会查询数据库
    User user2 = mapper.findById(41);
    System.out.println(user2);
}

三、注解开发

3.1 单表CRUD注解

在 SqlMapConfig.xml 中配置Mapper接口所在的包:

复制代码
<mappers>
    <package name="com.qcbyjy.mapper"/>
</mappers>

UserMapper接口:

复制代码
public interface UserMapper {
    
    @Select("select * from user")
    @Results(id="userMap", value={
        @Result(id=true, column="id", property="id"),
        @Result(column="username", property="username"),
        @Result(column="birthday", property="birthday"),
        @Result(column="sex", property="sex"),
        @Result(column="address", property="address")
    })
    public List<User> findAll();
    
    @Select("select * from user where id = #{uid}")
    @ResultMap("userMap")
    public User findById(Integer uid);
    
    @Insert("insert into user (username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})")
    public void insert(User user);
    
    @Update("update user set username = #{username},birthday=#{birthday},sex=#{sex},address=#{address} where id = #{id}")
    public void update(User user);
    
    @Delete("delete from user where id = #{id}")
    public void delete(Integer userId);
    
    @Select("select count(*) from user")
    public Integer findByCount();
    
    @Select("select * from user where username like #{username}")
    public List<User> findByUsername(String username);
}

3.2 多对一注解查询(延迟加载)

复制代码
public interface AccountMapper {
    
    @Select("select * from account")
    @Results(value={
        @Result(id=true, column="aid", property="id"),
        @Result(column="uid", property="uid"),
        @Result(column="money", property="money"),
        @Result(property="user", javaType=User.class, column="uid",
                one=@One(select="com.qcbyjy.mapper.UserMapper.findById", 
                         fetchType=FetchType.LAZY))
    })
    public List<Account> findAll();
}

3.3 一对多注解查询(延迟加载)

复制代码
public interface UserMapper {
    
    @Select("select * from user")
    @Results(id="userMap", value={
        @Result(id=true, column="id", property="id"),
        @Result(column="username", property="username"),
        @Result(column="birthday", property="birthday"),
        @Result(column="sex", property="sex"),
        @Result(column="address", property="address"),
        @Result(property="accounts", column="id",
                many=@Many(select="com.qcbyjy.mapper.AccountMapper.findByUid", 
                          fetchType=FetchType.LAZY))
    })
    public List<User> findAll();
}

public interface AccountMapper {
    @Select("select * from account where uid = #{uid}")
    public List<Account> findByUid(Integer uid);
}

四、总结

|-------|-------------|---------------------|
| 特性 | XML方式 | 注解方式 |
| 简单语句 | 支持 | 支持,更简洁 |
| 复杂语句 | 支持 | 较复杂 |
| 动态SQL | 支持良好 | 支持但较繁琐 |
| 可读性 | 较高 | 高(简单语句) |
| 推荐场景 | 复杂SQL、动态SQL | 简单SQL、Spring Boot项目 |

实际开发建议:简单SQL可以使用注解方式,复杂SQL和动态SQL建议使用XML方式-。

相关推荐
java1234_小锋1 小时前
【免费】基于Spark实时交通流量分析与拥堵预测系统(Java版本+可视化大屏+Kafka+SpringBoot+Vue3) 锋哥原创出品,必属精品
java·大数据·spark·kafka·实时交通流量分析与拥堵预测
组合缺一1 小时前
Solon 的 10 种 HTTP 服务器:改一行依赖,换一个引擎
java·服务器·网络协议·http·solon
LSL666_1 小时前
SpringBoot静态资源映射
java·spring boot·spring
520拼好饭被践踏2 小时前
JAVA+Agent学习day26
java·开发语言·数据结构·学习·agent
郝学胜-神的一滴2 小时前
力扣 692:巧用小顶堆高效求解前K个高频单词
java·数据结构·python·程序人生·算法·leetcode·职场和发展
zzzll11113 小时前
SpringBoot 入门与实践指南
java·spring boot·后端
AI人工智能+电脑小能手3 小时前
【大白话说Java面试题 第211题】【10_网络协议篇】第2题:说一下什么是 HTTP 协议?
java·网络协议·http·https·web通信
caishenzhibiao3 小时前
缠论画线主图 同花顺期货通指标
java·c语言·c#
晨曦中的暮雨3 小时前
Redis 有哪些常见数据结构?它们的底层实现和使用场景是什么?
java·后端·八股