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

相关推荐
lisin-lee-cooper6 分钟前
简单聊聊 OpenFeign 框架源码
java·微服务
Buke..21 分钟前
【APP 逆向】哔哩哔哩 sign 参数逆向(下):OLLVM 混淆还原 sign 算法
java·javascript·爬虫·python·算法
风流 少年40 分钟前
Spring AI 2.0:阿里云百炼平台(智能体应用)
redis·spring·阿里云
半生过往1 小时前
前端学 Java 课程笔记
java·前端·笔记
mmsx1 小时前
基于 Android 的校园信息管理系统源码
android·java·okhttp
Buke..1 小时前
【APP 逆向】哔哩哔哩 sign 参数逆向(上):Frida 反调试绕过与 unidbg 调用
java·开发语言·爬虫·python·安卓
竹枝溪1 小时前
Tomcat与Servlet全套小白教程
java·servlet·tomcat·cookie·filter·session·listener
UseLessQQ2 小时前
云计算k8s集群部署
java·kubernetes·云计算
我命由我123452 小时前
人脸识别 - 人脸识别选帧
java·人工智能·python·算法·安全·java-ee·人脸识别
宠友信息2 小时前
IM系统开发技术路线分析,即时通讯源码助力快速搭建聊天应用
java·spring boot·redis·websocket·mysql·uni-app·vue