一、延迟加载策略
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方式-。