Mybatis延迟加载策略
通过前面的学习,我们已经掌握了 Mybatis 中一对一,一对多,多对多关系的配置及实现,可以实现对象的 关联查询。实际开发过程中很多时候我们并不需要总是在加载用户信息时就一定要加载他的账户信息。此时就是我 们所说的延迟加载。
问题:在一对多中,当我们有一个用户,它有100个账户。
在查询用户的时候,要不要把关联的账户查出来?
在查询账户的时候,要不要把关联的用户查出来?
在查询用户时,用户下的账户信息应该是,什么时候使用,什么时候查询的。
在查询账户时,账户的所属用户信息应该是随着账户查询时一起查询出来。
什么是延迟加载?
在真正使用数据时才发起查询,不用的时候不查询。按需加载(懒加载)
什么是立即加载?
不管用不用,只要一调用方法,马上发起查询。
在对应的四种表关系中:一对多,多对一,一对一,多对多
一对多,多对多:通常情况下我们采用延迟加载
多对一,一对一:通常情况下我们采用立即加载。
我们之前在实现多表操作时,我们使用了resultMap来实现一对一,一对多,多对多关系的操作。主要是通过 association
、collection
实现一对一及一对多映射。
association、collection具备延迟加载功能。
1. 使用 assocation 实现延迟加载
需求: 查询账户信息同时查询用户信息。
① IAccountDao
/**
* 查询所有的账户
*
* @return
*/
List<Account> findAll();
② IAccountDao.xml
配置文件
<!--定义封装account和user的resultMap-->
<resultMap id="accountUserMap" type="account">
<id property="id" column="aid"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!--一对一的关系映射,配置封装user的内容
select属性指定的内容:查询用户的唯一标识
column属性指定的内容:用户根据id查询的时候,所需要的参数的值
-->
<association property="user" javaType="user"
select="com.veeja.dao.IUserDao.findById"
column="uid">
</association>
</resultMap>
<!-- 查询所有的操作 -->
<select id="findAll" resultMap="accountUserMap">
select * from account
</select>
③ 用户的持久层接口和映射文件
IUserDao:
/**
* 查询所有的用户,同时获取到用户下所有账户的信息
*
* @return
*/
List<User> findAll();
IUserDao.xml:
<!--根据id查询用户信息-->
<select id="findById" parameterType="INT" resultType="user">
select * from user where id = #{uid}
</select>
④ 开启mybatis的延迟加载策略
我们需要在 Mybatis 的配置文件 SqlMapConfig.xml 文件中添加延迟加载的配置。
<!--开启延迟加载策略-->
<settings>
<!--打开延迟加载的开关-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--将积极加载改为消息加载即按需加载-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
⑤ 测试只查询账户信息,不查询用户信息
/**
* 测试查询所有的账户,并且返回用户的名称和地址信息
*/
@Test
public void testFindAll(){
// 5. 执行查询所有方法
List<Account> accounts = accountDao.findAll();
//for (AccountUser accountUser: accountUsers) {
// System.out.println(accountUser);
//}
}
我们看一下控制台的输出内容:
2. 使用collection来实现延迟加载
需求:完成加载用户对象时,查询该用户所拥有的账户信息。
① IUserDao:
/**
* 查询所有的用户,同时获取到用户下所有账户的信息
*
* @return
*/
List<User> findAll();
② IUserDao.xml:
<!--定义user的resultMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!--user对象中account集合的配置-->
<collection property="accounts" ofType="account"
select="com.veeja.dao.IAccountDao.findAccountByUid"
column="id">
</collection>
</resultMap>
<!-- 查询所有的操作 -->
<select id="findAll" resultMap="userAccountMap">
SELECT * from user
</select>
③ IAccountDao
和IAccountDao.xml
映射配置文件
IAccountDao:
/**
* 通过用户的id,查询用户的所有账户
* @return
*/
List<Account> findAccountByUid(Integer uid);
IAccountDao.xml:
<!-- 查询所有的操作 -->
<select id="findAccountByUid" resultType="account">
select * from account where uid = #{uid}
</select>
④ 测试只查询用户信息,不查询用户的账户信息
/**
* 测试查询所有
*/
@Test
public void testFindAll() {
// 5. 执行查询所有方法
List<User> users = userDao.findAll();
// for (User user : users) {
// System.out.println("--------------------用户--------------------------");
// System.out.println(user);
// System.out.println(user.getAccounts());
// }
}
输出结果:
END.
转载:https://blog.csdn.net/u014565127/article/details/105912710