09.【多表查询实现延迟加载】

概念

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

  • 在查询用户的时候,要不要把关联的账户查出来?
  • 在查询账户的时候,要不要把关联的用户查出来?

在查询用户时,用户下的账户信息应该是,在使用的时候再查询的。

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

什么是延迟加载

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

什么是立即加载

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

何时使用延迟加载

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

  1. 一对多,多对多:通常情况下我们都是采用延迟加载
  2. 多对一,一对一:通常情况下我们都是采用立即加载

一对一延迟加载

1. SqlMapConfig.xml

  • lazyLoadingEnabled:开启mybatis支持延迟加载
  • aggressiveLazyLoading:触发方法立即加载,否则按需加载,默认就是false
 	<!--配置参数-->
    <settings>
        <!--开启mybatis支持延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--触发方法立即加载,否则按需加载,默认就是false-->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>

2.还需要配置映射文件:IAccount.xml

  • select属性:指定查询用户的唯一标识

    select="com.itheima.dao.IUserDao.findById"

    调用IUserDao.xml下的【根据id查询用户】

    属性里填写的是【namespace + id 】:IUserDao.xml的namespace和根据id查询用户的id

  • column属性:用户根据id查询时,所需要的参数的值

    findById方法用的id就是来自于此

  • javaType属性:封装到哪个对象

    javaType="user"

<resultMap id="accountUserMap" type="account">
        <!--下面是数据的封装-->
        <id property="id" column="id"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
        <!-- 一对一的关系映射:配置封装user的内容-->
        <association property="user" column="uid" select="com.itheima.dao.IUserDao.findById" javaType="user"></association>
    </resultMap>

具体实现

配置映射文件:IAccount.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.itheima.dao.IAccountDao">

    <!-- 定义封装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>
        <!-- 一对一的关系映射:配置封装user的内容-->
        <!-- javaType="user" : 封装到哪个对象 -->
        <!-- select属性:指定查询用户的唯一标识  namespace + id :IUserDao.xml的namespace和根据id查询用户的id-->
        <!-- column属性:用户根据id查询时,所需要的参数的值 (findById方法用的id就是来自于此)-->
        <association property="user" column="uid" select="com.itheima.dao.IUserDao.findById" javaType="user"></association>
    </resultMap>

   <!-- 查询所有 -->
    <select id="findAll" resultMap="accountUserMap">
        select * from account
    </select>
</mapper>

接口:IUserDao.java

	/**
     * 根据id查询用户信息
     */
    User findById(Integer userId);

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">
<mapper namespace="com.itheima.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集合的映射 -->
        <!-- ofType="account":集合中元素的类型  若未起别名,则要写全限定类名 -->
        <collection property="accounts" ofType="account">
            <!--  column="aid" 数据库列名(起别名了,避免列明重复) property="id":实体类中属性名称-->
            <id property="id" column="aid"></id>
            <result property="uid" column="uid"></result>
            <result property="money" column="money"></result>
        </collection>
    </resultMap>

    <!-- 根据id查询用户 -->
    <select id="findById" parameterType="INT" resultType="user">
        select * from user where id = #{uid}
    </select>

</mapper>

SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 配置properties-->
    <properties resource="jdbcConfig.properties"></properties>
    
    <!--配置参数-->
    <settings>
        <!--开启mybatis支持延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--触发方法立即加载,否则按需加载,默认就是false-->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>

    <!--使用typeAliases配置别名,它只能配置domain中类的别名 -->
    <typeAliases>
        <package name="com.itheima.domain"></package>
    </typeAliases>

    <!--配置环境-->
    <environments default="mysql">
        <!-- 配置mysql的环境-->
        <environment id="mysql">
            <!-- 配置事务 -->
            <transactionManager type="JDBC"></transactionManager>

            <!--配置连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"></property>
                <property name="url" value="${jdbc.url}"></property>
                <property name="username" value="${jdbc.username}"></property>
                <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>
    </environments>
    <!-- 配置映射文件的位置 -->
    <mappers>
        <package name="com.itheima.dao"></package>
    </mappers>
</configuration>

Test

	/**
     * 测试查询所有账户,同时包含用户名称和地址
     */
    @Test
    public void testFindAll(){
        List<Account> accounts = accountDao.findAll();
        /*for(Account account : accounts){
            System.out.println(account);
            System.out.println(account.getUser());
        }*/
    }

结果:
在这里插入图片描述

一对多延迟加载

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">
<mapper namespace="com.itheima.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集合的映射 -->
        <!-- ofType="account":集合中元素的类型  若未起别名,则要写全限定类名 -->
        <collection property="accounts" ofType="account" select="com.itheima.dao.IAccountDao.findAccountByUid" column="id"></collection>
    </resultMap>

    <!-- 查询所有 -->
    <select id="findAll" resultMap="userAccountMap">
        select * from user
    </select>

</mapper>

接口:IAccountDao

    /**
     * 根据用户id查询账户信息
     */
    List<Account> findAccountByUid(Integer uid);

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.itheima.dao.IAccountDao">

    <!-- 定义封装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>
        <!-- 一对一的关系映射:配置封装user的内容-->
        <!-- javaType="user" : 封装到哪个对象 -->
        <!-- select属性:指定查询用户的唯一标识  namespace + id :IUserDao.xml的namespace和根据id查询用户的id-->
        <!-- column属性:用户根据id查询时,所需要的参数的值 (findById方法用的id就是来自于此)-->
        <association property="user" column="uid" select="com.itheima.dao.IUserDao.findById" javaType="user"></association>
    </resultMap>

    <!-- 根据用户id查询账户列表 -->
    <select id="findAccountByUid" resultType="account">
        select * from account where uid = #{uid}
    </select>
</mapper>

Test

	/**
     * 测试查询所有
     */
    @Test
    public void testFindAll(){
        List<User> users = userDao.findAll();
       /* for(User user : users){
            System.out.println("-----每个用户的信息------");
            System.out.println(user);
            System.out.println(user.getAccounts());
        }*/
    }
发布了36 篇原创文章 · 获赞 14 · 访问量 3586

猜你喜欢

转载自blog.csdn.net/qq_39720594/article/details/105231948