07-延迟加载

10- 延迟加载

延迟加载又称为懒加载,按需加载。每次只查询1张表,当需要另一张关联表中的数据的时候,再发送一条SQL语句去查询另一张表中数据。

一对一关联查询使用标签:association

一对多关联查询使用标签:collection

10.1 项目环境

10.1.1 项目目录

10.1.2 SQL数据库语句

-- 1. 查询1号用户的信息
select * from user where id=1;

-- 2. 查询1号用户的扩展信息
select * from user_info where id=1;

10.1.3 用户接口

package cn.guardwhy.dao;

import cn.guardwhy.domain.User;
import cn.guardwhy.domain.UserInfo;

/**
 * 持久化接口:UserMapper
 */
public interface UserMapper {
    
    
    /**
     * 通过id查询1个用户
     */
    User findUserById(int id);

    /**
     * 通过id查询1个用户扩展信息
     */
    UserInfo findUserInfoById(int id);
}

10.1.4 UserMapper.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="cn.guardwhy.dao.UserMapper">
    <!--通过id查询1个用户-->
    <select id="findUserById" resultType="User">
        select * from user where id = #{id}
    </select>

    <!--通过id查询一个用户的拓展信息-->
    <select id="findUserInfoById" resultType="userInfo">
        select * from user_info where id = #{id}
    </select>
</mapper>

10.1.5 测试代码

package cn.guardwhy.test;

import cn.guardwhy.dao.UserMapper;
import cn.guardwhy.domain.User;
import cn.guardwhy.domain.UserInfo;
import cn.guardwhy.utils.SessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TestUserMapper {
    
    
    private static SqlSessionFactory factory;
    private SqlSession session;
    private UserMapper userMapper;

    // 创建会话对象,自动提交事务
    @Before
    public void begin(){
    
    
        session = SessionFactoryUtils.getSession();
        userMapper = session.getMapper(UserMapper.class);
    }

    @Test
    public void testFindUserAndInfo(){
    
    
        User user = userMapper.findUserById(1);
        System.out.println("用户信息:" + user);

        UserInfo info = userMapper.findUserInfoById(1);
        System.out.println("用户拓展信息:" + info);
    }

    // 关闭会话
    @After
    public void end(){
    
    
        // 手动提交
        session.commit();
        session.close();
    }
}

10.1.6 执行结果

10.2 一对一的延迟加载

10.2.1需求案例

通过id查询1号用户User的基本信息,显示用户名和性别
使用延迟加载的方式,关联查询出对应的用户扩展信息UserInfo,身高和体重。

10.2.2 UserMapper.xml

1) 生成步骤:

  1. 通过id查询用户扩展信息,查询id为findUserInfoById,指定查询结果为userInfoMap。
  2. 配置映射id为userAndInfoMap中配置关联映射association,指定property、column和select属性。
  3. 指定select为上面的findUserInfoById查询,column指定用户主表中的主键id。
  4. 根据用户id查询用户基本信息,指定查询结果为userAndInfoMap。
association标签的属性 说明
property 另一方的属性名
column 主表的主键
select 通过主键再去查询的SQL语句
<?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="cn.guardwhy.dao.UserMapper">
    <!--创建User的映射-->
    <resultMap id="userMap" type="user">
        <!--映射主键-->
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="birthday" column="birthday"/>
        <result property="sex" column="sex"/>
        <result property="address" column="address"/>
    </resultMap>

    <!--创建UserInfo的映射-->
    <resultMap id="userInfoMap" type="userInfo">
        <!--映射主键-->
        <id property="id" column="id"/>
        <result property="height" column="height"/>
        <result property="weight" column="weight"/>
        <result property="married" column="married"/>
    </resultMap>

    <!--创建一对一的关联extends,将上面的映射关系复制过来-->
    <resultMap id="userAndInfoMap" type="user" extends="userMap">
        <!--
        property:另一方的属性名
        column:主表中主键列
        select: 查询另一方的SQL语句
        -->
        <association property="userInfo" column="id" select="findUserInfoById"/>
    </resultMap>

    <!--通过id查询1个用户-->
    <select id="findUserById" resultMap="userAndInfoMap">
        select * from user where id = #{id}
    </select>

    <!--通过id查询一个用户的拓展信息-->
    <select id="findUserInfoById" resultMap="userInfoMap">
        select * from user_info where id = #{id}
    </select>
</mapper>

10.2.3 开启延迟加载

sqlMapConfig.xml中开启延迟加载的settings中的lazyLoadingEnabled

<!--开启延迟加载-->
<settings>
    <setting name="lazyLoadingEnabled" value="true"/>
</settings>

10.2.4 测试代码

  1. 通过id查询用户对象
  2. 输出用户名和性别的属性
  3. 查询用户之后,再查询用户扩展信息
@Test
public void testFindUserById(){
    
    
    User user = userMapper.findUserById(1);
    System.out.println("用户名:" + user.getUsername() + ", 性别:" + user.getSex());
    // 需要用户的拓展信息
    UserInfo userInfo = user.getUserInfo();
    System.out.println("身高:" + userInfo.getHeight() + ", 体重:" + userInfo.getWeight());
}

10.2.5 执行结果

10.3 一对多的延迟加载

10.3.1 需求案例

查询1号用户的订单信息。
查询1号用户数据,并且关联查询出这个用户所有的订单数据,使用延迟加载方式实现。

10.3.2 SQL数据表查询

-- 查询1号用户的信息
select * from user where id=1;

-- 查询1号用户的订单信息
select * from order_form where user_id=1;

10.3.3 编写用户接口

/**
 * 通过id查询1个用户
*/
User findUserById(int id);

/**
* 通过id查询1个用户扩展信息
*/
UserInfo findUserInfoById(int id);

/**
  通过userId查询这个用户所有的订单信息
*/
List<OrderForm> findOrdersByUserId(int userId);

10.3.4 UserMapper.xml

  1. 保留订单表的映射orderMap
  2. 增加根据用户id查询订单数据配置
  3. 修改userAndInfoMap映射,添加collection标签,指定select和column属性
select为findOrdersByUserId。
column为user主表中的主键id

注意:这里与association关联配置到一起了,也可以分开映射。

<?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="cn.guardwhy.dao.UserMapper">
    <!--创建User的映射-->
    <resultMap id="userMap" type="user">
        <!--映射主键-->
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="birthday" column="birthday"/>
        <result property="sex" column="sex"/>
        <result property="address" column="address"/>
    </resultMap>

    <!--创建订单的映射-->
    <resultMap id="orderMap" type="orderForm">
        <id property="id" column="id"/>
        <result property="userId" column="user_id"/>
        <result property="number" column="number"/>
        <result property="createTime" column="crate_time"/>
        <result property="note" column="note"/>
    </resultMap>

    <!--创建UserInfo的映射-->
    <resultMap id="userInfoMap" type="userInfo">
        <!--映射主键-->
        <id property="id" column="id"/>
        <result property="height" column="height"/>
        <result property="weight" column="weight"/>
        <result property="married" column="married"/>
    </resultMap>
    
    <!--查询某个用户的订单信息-->
    <select id="findOrdersByUserId" resultMap="orderMap">
        select * from order_form where user_id= #{id};
    </select>

    <!--创建一对一的关联extends,将上面的映射关系复制过来-->
    <resultMap id="userAndInfoMap" type="user" extends="userMap">
        <!--
        property:另一方的属性名
        column:主表中主键列
        select: 查询另一方的SQL语句
        -->
        <association property="userInfo" column="id" select="findUserInfoById"/>

        <!--创建一对多的关联-->
        <collection property="orders" column="id" select="findOrdersByUserId"/>
    </resultMap>

    <!--通过id查询1个用户-->
    <select id="findUserById" resultMap="userAndInfoMap">
        select * from user where id = #{id}
    </select>

    <!--通过id查询一个用户的拓展信息-->
    <select id="findUserInfoById" resultMap="userInfoMap">
        select * from user_info where id = #{id}
    </select>
</mapper>

10.3.5 测试代码

/**
 * 一对多的延迟加载
*/
@Test
public void testFindUserById2(){
    
    
    User user = userMapper.findUserById(1);
    System.out.println("用户名:" + user.getUsername() + ", 性别:" + user.getSex());
    // 使用订单信息
    List<OrderForm> orders = user.getOrders();
    orders.forEach(System.out::println);
}

10.3.6 执行结果

猜你喜欢

转载自blog.csdn.net/hxy1625309592/article/details/113528241