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

相关推荐
IT_Octopus12 小时前
IntelliJ 本地日志路径自定义:`-DLOG_PATH=./logs` 为什么总“不听话“
java·log4j·intellij-idea
长征coder12 小时前
【无标题】
java·性能优化
新时代牛马13 小时前
PCI与PCIe 硬件原理、配置空间/BAR 与 Linux 驱动完整篇:从 LTSSM、TLP 到 ECAM 与probe
java·linux·服务器
Bs_MoneyMagnet13 小时前
基于springboot+vue的医疗健康便民服务平台的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring
sunshine22 girl14 小时前
Java学习一 环境配置2 Idea的入门使用和maven配置,项目启动脚本配置
java·maven
有点。14 小时前
*C++哈夫曼树与哈夫曼编码
java·c++·servlet
CRMEB系统商城15 小时前
CRMEB标准版系统(Java)v3.1正式发布
java·spring·微信小程序·php·教育电商
写后端的胖头鱼15 小时前
【高频面试题】Java 基础类型 + 包装类 + String 互相转换
java·开发语言
weixin_4604435615 小时前
企业考试系统从.NET迁移到Java+Linux:数据库迁移、接口兼容与灰度切换实践
java·煤矿培训考试系统·煤矿在线考试系统·煤矿安全培训·煤矿考试系统·一人一档
香菜TTT16 小时前
Redis的哨兵机制
java·数据库·redis