Mybatis入门笔记(10)——延迟加载

问题:

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

在查询用户时,用户下的账户信息是,什么时候用,什么时候再查询。

在查询账户时,账户的所属用户信息应该是随着账户查询时再查询出来。

什么是延迟加载

延迟加载

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

立即加载

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

在对应的四种表关系中,通常情况下,我们采用下面的方法加载

表类型 加载方式
一对多、一对多 延迟加载
多对一、一对一 立即加载

一对一实现延迟加载

需求:

查询账户信息同时查询用户信息,延迟加载用户信息。

截图如下:

代码详见mybatisdemo8

步骤:

  1. 编写账户的dao接口

    public interface IAccountDao {
        //查询所有,同时还有获取到当前账户的所属用户信息
        List<Account> findAll();
    }
    
  2. 账户的映射配置文件

    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>
    
  3. 用户的持久层接口

    public interface IUserDao {
        // 通过ID查询一个用户
        User findUserById(Integer id);
    }
    
  4. 用户的映射配置文件

    <?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>
    
  5. 在SqlMapconfig.xml中开启mybatis的延迟加载策略

    <!--配置参数-->
    <settings>
        <!--开启Mybatis支持延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"></setting>
    </settings>
    
  6. 编写测试只查账户信息不查用户信息

    @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对象的查询。

一对多实现延迟加载

  1. 编写用户和账户的持久层接口的方法

    /**
     * 查询所有用户,同时获取到用户下所有账户的信息
     * @return
     */
    List<User> findAll();
    
    /**
     * 根据用户id查询账户信息
     * @param uid
     * @return
     */
    List<Account> findAccountByUid(Integer uid);
    
  2. 编写用户持久层映射配置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>
    
  3. 编写账户持久层映射配置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>
    
  4. 测试只加载用户信息

    //查询所有用户
    @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账户信息;

原文地址:https://www.cnblogs.com/benjieqiang/p/11217842.html