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方式-。

相关推荐
budingxiaomoli4 小时前
Spring统一功能处理
java·后端·spring
Flynn Liang6 小时前
可观测性与成本治理:一次对话的 17 个观测点
java·langchain·可观测性·micrometer·langchain4j·token 成本·llm 监控
金銀銅鐵6 小时前
带您看懂字节码指令(三):同一行加法,为什么有四种指令
java·jvm
文丑颜不良啊10 小时前
LeetCode2821~2840题目解析
java·leetcode
apcipot_rain11 小时前
C++转Java日记(10)
java·开发语言
简 洁 冬冬11 小时前
泛型方法写法全面辨析:从「能编译」到「能跑」到「能用」
java·泛型
LGL6030A12 小时前
Java学习历程31——初识Spring Boot
java·spring boot·学习
阿达和自己13 小时前
springboot学习-springboot引入MyBatis-Plus
spring boot·学习·mybatis
Lansonli13 小时前
大数据Spark(八十八):Spark任务资源之Standalone集群测试
java·服务器·spark
budingxiaomoli14 小时前
Spring AOP
java·spring·java-ee