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