MyBatis延迟加载

1.概念

问题:在一对多中,当我们有一个用户,它有100个账户。

​ 在查询用户时,用户下的账户信息应该是什么时候使用和查询的

​ 在查询账户时,账户的所属信息应该是随着账户查询时一起查询出来

什么是延迟加载

在真正使用数据时才发起查询,不用的时候不查询。按需加载(懒加载)

什么是立即加载

不管用不用,只要一调用方法,马上发起查询

在对应的四种表关系中:一对多,多对一,一对一,多对多

​ 一对多,多对多:通常情况下都采用延迟加载

​ 多对一,一对一:通常情况下采用立即加载

2.使用 assocation 实现延迟加载

需求:查询账户信息同时查询用户信息。

  1. 在 Mybatis 的配置文件 SqlMapConfig.xml 文件中添加延迟加载的配置。
1
2
3
4
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
  1. 账号的持久层AccountDao接口和持久层映射文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
List<Account> findAll();

<mapper namespace="cn.hxx.Dao.AccountDao">
<!--定义封装account和user的resultMap-->
<resultMap id="accountUserMap" type="account">
<id property="id" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<association property="user" javaType="User" select="cn.hxx.Dao.UserDao.findById" column="uid">
<!--
select: 填写我们要调用的 select 映射的 id ,根据用户id查询用户信息,调用的是UserDao中的findById方法
column : 填写我们要传递给 select 映射的参数,传递给findById的方法是 sql查询出来的uid
-->
</association>
</resultMap>
<select id="findAll" resultType="account">
select * from account;
</select>
</mapper>
  1. 用户UserDao的持久层接口和配置文件
1
2
3
4
5
User findById(Integer id);

<select id="findById" resultType="cn.hxx.domain.User" parameterType="Integer">
select * from user where id=#{uid};
</select>
  1. 测试
1
2
3
4
@Test
public void test1(){
List<Account> list = accountDao.findAll();
}
  1. 测试结果:因为本次只是将 Account对象查询出来放入 List 集合中,并没有涉及到 User对象,所以就没有

    ​ 发出 SQL 语句查询账户所关联的 User 对象的查询

3.使用 Collection 实现延迟加载

在一对多关系配置的< collection >结点中配置延迟加载策略。< collection >结点中也有 select 属性,column 属性。

需求:完成加载用户对象时,查询该用户所拥有的账户信息。

  1. 用户类中添加账户列表
1
2
3
4
5
6
7
8
9
public class User1 {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
//一对多关系映射,主表实体应该包含从表实体的集合引用
private List<Account1> accounts;
}
  1. 编写用户和账户持久层接口的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public interface UserDao {
//查询所有用户
List<User1> findAll1();
}
<!--配置collection实现延迟加载-->
<resultMap id="AllUser1Map" type="user1">
<id column="id" property="id"></id>
<result column="username" property="username"></result>
<result column="sex" property="sex"></result>
<result column="address" property="address"></result>
<result column="birthday" property="birthday"></result>
<collection property="accounts" ofType="account1"
select="cn.hxx.Dao.AccountDao.findByUid"
column="id">
</collection>
</resultMap>
<!--配置查询所有User1,id是UserDao的方法名-->
<select id="findAll1" resultMap="AllUser1Map">
select * from user;
</select>
  1. 账号的持久层AccountDao接口和持久层映射文件
1
2
3
4
5
6
public interface AccountDao {
List<Account> findByUid(Integer uid);
}
<select id="findByUid" resultType="account">
select * from account where uid=#{id};
</select>
  1. 测试
1
2
3
4
5
6
7
8
@Test
public void test14(){
/*测试collection延迟加载*/
List<User1> user1s = mapper.findAll1();
/*for (User1 user1 : user1s) {
System.out.println(user1);
}*/
}