Mybatis入门笔记(10)——延迟加载
问题:
在一对多中,当我们有一个用户,它有100个账户。
在查询用户时,用户下的账户信息是,什么时候用,什么时候再查询。
在查询账户时,账户的所属用户信息应该是随着账户查询时再查询出来。
什么是延迟加载
延迟加载
在真正使用数据时才发起查询,不用的时候不查询。按需加载(懒加载)
立即加载
不管用不用,只要一调用方法,马上发起查询。
在对应的四种表关系中,通常情况下,我们采用下面的方法加载
表类型 | 加载方式 |
---|---|
一对多、一对多 | 延迟加载 |
多对一、一对一 | 立即加载 |
一对一实现延迟加载
需求:
查询账户信息同时查询用户信息,延迟加载用户信息。
截图如下:
代码详见mybatisdemo8
步骤:
-
编写账户的dao接口
public interface IAccountDao { //查询所有,同时还有获取到当前账户的所属用户信息 List<Account> findAll(); }
-
账户的映射配置文件
select: 填写我们要调用的 select 映射的 id
column : 填写我们要传递给 select 映射的参数<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ben.dao.IAccountDao"> <!-- 定义封装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" column="uid" javaType="user" select="com.ben.dao.IUserDao.findUserById"></association> </resultMap> <!-- 查询所有 --> <select id="findAll" resultMap="accountUserMap"> select * from account </select> </mapper>
-
用户的持久层接口
public interface IUserDao { // 通过ID查询一个用户 User findUserById(Integer id); }
-
用户的映射配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespace:用来区别不同的类的名字 --> <mapper namespace="com.ben.dao.IUserDao"> <!-- 通过Id查询一个用户 --> <select id="findUserById" parameterType="Integer" resultType="com.ben.domain.User"> select * from user where id = #{v} </select> </mapper>
-
在SqlMapconfig.xml中开启mybatis的延迟加载策略
<!--配置参数--> <settings> <!--开启Mybatis支持延迟加载--> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"></setting> </settings>
-
编写测试只查账户信息不查用户信息
@Test public void testFindAll(){ List<Account> list = accountDao.findAll(); for (Account account : list) { System.out.println("--------每个account的信息------------"); System.out.println(account); System.out.println(account.getUser()); } }
很显然,本次只是将Account对象查询出来方式List结合中,并没有涉及到User对象,所以就没有发出Sql余数查询账户所关联的User对象的查询。
一对多实现延迟加载
-
编写用户和账户的持久层接口的方法
/** * 查询所有用户,同时获取到用户下所有账户的信息 * @return */ List<User> findAll(); /** * 根据用户id查询账户信息 * @param uid * @return */ List<Account> findAccountByUid(Integer uid);
-
编写用户持久层映射配置IUserDao.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespace:用来区别不同的类的名字 --> <mapper namespace="com.ben.dao.IUserDao"> <!-- 定义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对象中accounts集合的映射 --> <collection property="accounts" ofType="account" select="com.ben.dao.IAccountDao.findAccountByUid" column="id"></collection> </resultMap> <!-- 查询所有 --> <select id="findAll" resultMap="userAccountMap"> select * from user </select> <!-- 通过Id查询一个用户 --> <select id="findUserById" parameterType="Integer" resultType="com.ben.domain.User"> select * from user where id = #{v} </select> </mapper>
-
编写账户持久层映射配置IAccountDao.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ben.dao.IAccountDao"> <!-- 定义封装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" column="uid" javaType="user" select="com.ben.dao.IUserDao.findUserById"></association> </resultMap> <!-- 查询所有 --> <select id="findAll" resultMap="accountUserMap"> select * from account </select> <!-- 根据用户id查询账户列表 --> <select id="findAccountByUid" resultType="account"> select * from account where uid = #{uid} </select> </mapper>
-
测试只加载用户信息
//查询所有用户 @Test public void testFindAll(){ List<User> list = userdao.findAll(); // for (User user : list) { // System.out.println("----每个用户的信息----"); // System.out.println(user); // System.out.println(user.getAccounts()); // } }
并未加载Account账户信息;