Mybatis动态sql、if与where的使用、sql片段、foreach遍历、Mybatis的关联查询一对一、一对多、多对多、Mybatis的延时加载-day02

第一节 Mybatis的动态SQL

1.1 if 和where的使用

  • if标签:是作为判断参数来使用的,如果符合条件,就把if标签体内的SQL拼接上,不符合条件就不拼接
  • 注意:用if进行判断是否为空时,不仅要判断null,还要判断空字符串’'
  • where标签:会去掉条件中的第一个and符号
  1. 在UserMapper.java接口中写一个方法
    在这里插入图片描述
  2. 在UserMapper.xml中配置sql
    在这里插入图片描述
  3. 测试与效果
package com.it.test;

import com.it.mapper.UserMapper;
import com.it.model.User;
import com.it.vo.UserQueryVo;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * @ClassName Demo02
 * @Author shuyy
 * @Date 2020/9/22
 **/
public class Demo01 {
    
    

    SqlSession sqlSession;

    @Before
    public void before() throws IOException {
    
    
        System.out.println("before...获取session");
        //1.读取配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //3.通过SqlSessionFactory创建SqlSession
        sqlSession = sessionFactory.openSession();
    }

    @After
    public void after(){
    
    
        System.out.println("after...关闭session");
        //5.关闭SqlSession
        sqlSession.close();
    }
    @Test
    public void test1(){
    
    
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //System.out.println(userMapper);//返回的是一个代理对象
        //查询条件
        UserQueryVo queryVo = new UserQueryVo();
        User user = new User();
        user.setSex("男");
        user.setUsername("shu04");
        queryVo.setUser(user);
        List<User> list = userMapper.findUserList(queryVo);
        System.out.println(list);
        //sqlSession.commit();//增删改记得提交事务
    }
}

在这里插入图片描述
在这里插入图片描述

  1. 如果注释了姓名设置,会查询所有符合性别条件的
    在这里插入图片描述
  2. 如果注释了性别设置,虽然不会报错,但是查询不到结果,这是由于sql所致
    在这里插入图片描述
  3. 为了正确的使用sql,使用if与where来拼接sql,如果要查询的字段值为空,就不把该字段的条件加到sql上,起到动态拼接sql的效果
    在这里插入图片描述
	<!--if与where的使用--><!--查询性别和名字-->
    <select id="findUserList" parameterType="UserQueryVo" resultType="user">
        select * from user
        <where>
            <if test="user != null">
                <if test="user.sex != null and user.sex != ''">
                    sex = #{user.sex}
                </if>
                <if test="user.username != null and user.username != ''">
                    and username like '%${user.username}%'
                </if>
            </if>
        </where>
    </select>
  1. 注释一些配置的效果,就算注释了设置user,user为空也不报错
    在这里插入图片描述
  2. where会去除条件中第一个and符号(上面的语句中写的是and username like ‘%${user.username}%’),拼接后的语句中去除了and,防止了SQL错误
    在这里插入图片描述
  3. 注释了条件,就不拼接到对应的sql上
    在这里插入图片描述

1.2 SQL片断

  • Mybatis提供了SQL片段的功能,可以提高SQL的可重用性
    在这里插入图片描述
	<!--if与where的使用--><!--查询性别和名字-->
    <!--声明一个sql片段-->
    <sql id="select_user_where">
        <if test="user != null">
            <if test="user.sex != null and user.sex != ''">
                sex = #{user.sex}
            </if>
            <if test="user.username != null and user.username != ''">
                and username like '%${user.username}%'
            </if>
        </if>
    </sql>
    <select id="findUserList" parameterType="UserQueryVo" resultType="user">
        select * from user
        <where>
            <!--引用sql片段-->
            <include refid="select_user_where"/>
        </where>
    </select>
  • 成功执行
    在这里插入图片描述

1.3 foreach遍历

  1. 先在包装类中提供一个List,并提供get/set
    在这里插入图片描述
  2. 在UserMapper.java中提供一个方法
    在这里插入图片描述
  3. 在UserMapper.xml中提供对应的sql
    在这里插入图片描述
	<!--foreach的使用-->
    <select id="findUserByIds" parameterType="userQueryVo" resultType="user">
        select * from user
        <where>
            <if test="ids != null and ids.size > 0">
                <!--
                    foreach标签:表示一个foreach循环
                    collection:集合参数名称,如果是直接传入集合参数,则该处的参数名称只能填 list
                    item:每次遍历出来的对象
                    open:开始遍历时拼接的串(sql)
                    close:结束遍历时拼接的串(sql)
                    separator:遍历出的每个对象之间需要拼接的字符
                -->
                <foreach collection="ids" item="id" open="id in (" separator="," close=")">
                    ${id}
                </foreach>
            </if>
        </where>
    </select>
  1. 测试
package com.it.test;

import com.it.mapper.UserMapper;
import com.it.model.User;
import com.it.vo.UserQueryVo;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName Demo02
 * @Author shuyy
 * @Date 2020/9/22
 **/
public class Demo02 {
    
    

    SqlSession sqlSession;

    @Before
    public void before() throws IOException {
    
    
        System.out.println("before...获取session");
        //1.读取配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //3.通过SqlSessionFactory创建SqlSession
        sqlSession = sessionFactory.openSession();
    }

    @After
    public void after(){
    
    
        System.out.println("after...关闭session");
        //5.关闭SqlSession
        sqlSession.close();
    }
    @Test
    public void test1(){
    
    
        //通过session获取代理【jdk实现的代理】
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //System.out.println(userMapper);//返回的是一个代理对象
        //查询条件
        UserQueryVo queryVo = new UserQueryVo();
        List<Integer> ids = new ArrayList<Integer>();
        ids.add(34);
        ids.add(35);
        ids.add(36);
        queryVo.setIds(ids);
        List<User> list = userMapper.findUserByIds(queryVo);
        for (User user : list) {
    
    
            System.out.println(user);
        }
        //sqlSession.commit();//增删改记得提交事务
    }
}

在这里插入图片描述
在这里插入图片描述

参数是数组的遍历

  • 发现上面的使用有一些麻烦,直接在参数中传入数组
  1. 在UserMapper.java中提供方法
    在这里插入图片描述
  2. 在UserMapper.xml中提供对应的sql
    在这里插入图片描述
  3. 测试
    在这里插入图片描述

第二节 Mybatis的关联查询

2.1 案例:用户与订单

  • 在day01数据库表的基础上实现
    在这里插入图片描述
  • user和orders:
  1. User 与orders:一个用户可以创建多个订单,一对多
  2. Orders 与 user:多个订单可由一个用户创建,多对一
  • orders和orderdetail:
  1. Orders 与 orderdetail:一个订单可以包括 多个订单明细,因为一个订单可以购买多个商品,每个商品的购买信息在orderdetail记录,一对多关系
  2. orderdetail 与orders:多个订单明细包括在一个订单中, 多对一
  • orderdetail和items:
  1. Orderdetail 与 items:多个订单明细只对应一个商品信息,多对一
  2. Items 与 orderdetail:一个商品可以包括在多个订单明细 ,一对多
  • 需求:根据用户id查找订单信息,包括用户名和地址
    在这里插入图片描述
#查找id为1的所有订单
SELECT
	orders.id,
	orders.number,
	orders.createtime,
	orders.note,
	USER.username,
	USER.address
FROM
	orders,
	USER
WHERE
	orders.user_id = USER.id
AND USER.id = 1;

在这里插入图片描述
在这里插入图片描述

2.2 一对一(resultType实现)

  • 复杂查询时,单表对应的po类已不能满足输出结果集的映射,所以要根据需求建立一个扩展类来作为resultType的类型
  • 例如:查找某个订单id的信息,包括用户名和地址
    在这里插入图片描述
#查找某个订单id的信息,包括用户名和地址
SELECT
	o.*, u.username,
	u.address
FROM
	orders o,
	USER u
WHERE
	o.user_id = u.id
AND o.id = 3
  • 单个orders表的类型已无法满足,所以创建一个扩展类来满足需求

第一步:写一个订单类的扩展类

  • 原来的订单类,提供get/set,toString
    在这里插入图片描述
  • 订单扩展类OrdersExt,提供属性的get/set,toString(在toString中调用父类orders的toString)
    在这里插入图片描述

第二步:声明订单接口

在这里插入图片描述

第三步:声明订单配置文件

在这里插入图片描述

<?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.it.mapper.OrderMapper">
    <select id="findOrderById" parameterType="int" resultType="ordersExt">
        select
            o.*,u.username,u.address
        from
            orders o,user u
        where
            o.user_id = u.id
        and o.id = #{id}
    </select>
</mapper>

第四步:加载映射文件

在这里插入图片描述

第五步:测试

package com.it.test;

import com.it.mapper.OrderMapper;
import com.it.model.OrdersExt;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;

/**
 * @ClassName Demo02
 * @Author shuyy
 * @Date 2020/9/22
 **/
public class Demo03 {
    
    

    SqlSession sqlSession;

    @Before
    public void before() throws IOException {
    
    
        System.out.println("before...获取session");
        //1.读取配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //3.通过SqlSessionFactory创建SqlSession
        sqlSession = sessionFactory.openSession();
    }

    @After
    public void after(){
    
    
        System.out.println("after...关闭session");
        //5.关闭SqlSession
        sqlSession.close();
    }
    @Test
    public void test1(){
    
    
        //通过session获取代理【jdk实现的代理】
        OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
        //System.out.println(userMapper);//返回的是一个代理对象
        //查询条件
        OrdersExt orderById = orderMapper.findOrderById(3);
        System.out.println(orderById);
        //sqlSession.commit();//增删改记得提交事务
    }

}

在这里插入图片描述

2.3 一对一(resultMap实现)

  • 其实就是在模型里使用模型,association的使用

第一步:在Orders类中添加User模型,并提供get/set

  • User 订单所属的用户
    在这里插入图片描述

第二步:在订单Mapper接口中写一个方法

在这里插入图片描述

第三步:在订单配置文件中配置resultMap

在这里插入图片描述

	<!--如果模型里有模型,使用resultMap-->
    <resultMap id="ordersResultMap" type="orders">
        <!--与orders模型匹配数据-->
        <id column="id" property="id"></id>
        <id column="note" property="note"></id>
        <id column="number" property="number"></id>
        <id column="createtime" property="createtime"></id>

        <!--orders的user匹配数据
        模型里有模型,使用association来配置
        -->
        <association property="user" javaType="user">
            <id column="user_id" property="id"></id>
            <id column="username" property="username"></id>
            <id column="address" property="address"></id>
        </association>
    </resultMap>
    <select id="findOrderByMap" parameterType="int" resultMap="ordersResultMap">
        select
            o.*,u.username,u.address
        from
            orders o,user u
        where
            o.user_id = u.id
        and o.id = #{id}
    </select>

第四步:测试

	@Test
    public void test2(){
    
    
        //通过session获取代理【jdk实现的代理】
        OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
        //System.out.println(userMapper);//返回的是一个代理对象
        //查询条件
        Orders order = orderMapper.findOrderByMap(3);
        System.out.println(order);
        System.out.println(order.getUser());
        //sqlSession.commit();//增删改记得提交事务
    }

在这里插入图片描述

总结

  • resultType:resultType的使用较为简单,如果pojo中没有包括查询出的列名,可以通过增加对应属性的列名来完成映射。如果对于查询结果没有特殊的要求,建议使用resultType

  • resultMap:需要单独定义resultMap,实现起来有点麻烦,如果对查询结果有特殊的要求,使用resultMap可以将关联查询映射到pojo对象的属性中。

  • resultMap可以实现延迟加载,resultType则无法实现延迟加载。

2.4 一对多(resultMap+collection)

  • 其实就是在模型中使用集合,即collection的使用
  • 例如:根据订单id查找订单信息、用户信息和订单明细信息
    在这里插入图片描述
#根据订单id查找订单信息、用户信息和订单明细信息
SELECT
	o.*, u.username,
	u.address,
	od.id,
	od.items_id,
	od.items_num
FROM
	orders o,
	USER u,
	orderdetail od
WHERE
	o.user_id = u.id
AND o.id = od.orders_id
AND o.id = 3

第一步:写一个订单详情类

在这里插入图片描述

  • 属性与数据库字段对应,并提供get/set,toString
    在这里插入图片描述
package com.it.model;

public class OrdersDetail {
    
    

    private Integer id;//订单id
    private Integer items_id;//商品id
    private Integer items_num;//商品购买数量

    public Integer getId() {
    
    
        return id;
    }

    public void setId(Integer id) {
    
    
        this.id = id;
    }

    public Integer getItems_id() {
    
    
        return items_id;
    }

    public void setItems_id(Integer items_id) {
    
    
        this.items_id = items_id;
    }

    public Integer getItems_num() {
    
    
        return items_num;
    }

    public void setItems_num(Integer items_num) {
    
    
        this.items_num = items_num;
    }

    @Override
    public String toString() {
    
    
        return "OrdersDetail{" +
                "id=" + id +
                ", items_id=" + items_id +
                ", items_num=" + items_num +
                '}';
    }
}

第二步:Orders中添加订单详情

  • 并提供get/set
    在这里插入图片描述

第三步:OrderMapper接口中写方法

在这里插入图片描述

第四步:OrderMapper.xml中添加配置

在这里插入图片描述

	<!--一对多-->
    <resultMap id="ordersResultMap2" type="orders">
        <!--与orders模型匹配数据-->
        <id column="id" property="id"></id>
        <id column="note" property="note"></id>
        <id column="number" property="number"></id>
        <id column="createtime" property="createtime"></id>

        <!--orders的user匹配数据
        模型里有模型,使用association来配置
        -->
        <association property="user" javaType="user">
            <id column="user_id" property="id"></id>
            <id column="username" property="username"></id>
            <id column="address" property="address"></id>
        </association>
        <!--一对多匹配集合:往orders的orderDetails 匹配数据
        注意:集合里类型使用ofType,而不是javaType
        -->
        <collection property="ordersDetailList" ofType="ordersDetail">
            <id property="id" column="id"></id>
            <id property="items_id" column="items_id"></id>
            <id property="items_num" column="items_num"></id>
        </collection>
    </resultMap>
    <select id="findOrderByIdsMap" parameterType="int" resultMap="ordersResultMap2">
        select
            o.*,
            u.username,
            u.address,
            od.id,
            od.items_id,
            od.items_num
        from
            orders o,
            user u,
            orderdetail od
        where
            o.user_id = u.id
        and o.id = od.orders_id
        and o.id = #{id}
    </select>

第五步:测试

 	@Test
    public void test3(){
    
    
        /*一对多:模型里有集合*/
        //通过session获取代理【jdk实现的代理】
        OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
        //System.out.println(userMapper);//返回的是一个代理对象
        //查询条件
        Orders order = orderMapper.findOrderByIdsMap(3);
        System.out.println(order);
        System.out.println(order.getUser());
        System.out.println(order.getOrdersDetailList());
        //sqlSession.commit();//增删改记得提交事务
    }

在这里插入图片描述

2.5 多对多

  • 例如:查询用户信息及用户购买的商品信息,要求将关联信息映射到主pojo的pojo属性中
    在这里插入图片描述
  • 映射思路
  1. 将用户信息映射到user中。
  2. 在user类中添加订单列表属性List<Orders> orderslist,将用户创建的订单映射到orderslist
  3. 在Orders中添加订单明细列表属性List<Orderdetail> detailList,将订单的明细映射到detailList
  4. 在Orderdetail中添加Items属性,将订单明细所对应的商品映射到Items
#查询用户信息及用户购买的商品信息
SELECT
	u.id,
	u.username,
	u.address,
	o.id,
	o.number,
	o.createtime,
	o.note,
	od.id detail_id,
	od.items_id,
	od.items_num,
	it.name,
	it.price,
	it.detail
FROM
	orders o,
	USER u,
	orderdetail od,
	items it
WHERE
	o.user_id = u.id
AND o.id = od.orders_id
AND od.items_id = it.id

第一步:UserMapper接口中添加方法

在这里插入图片描述

第二步:User/Orders/Orderdetail.java

  1. User中添加订单,并提供get/set
    在这里插入图片描述
  2. Orders中还是保持之前添加的订单明细,提供get/set
    在这里插入图片描述
  3. 写一个商品详情类Items,属性与数据库字段对应
    在这里插入图片描述
  • 这里就提供自己需要的属性,并提供get/set、toString
    在这里插入图片描述
  1. 在订单详情(Orderdetail)中添加商品详情(Items),并提供get/set
    在这里插入图片描述

第三步:配置UserMapper.xml

在这里插入图片描述

	<!--查询用户信息及用户购买的商品信息-->
    <resultMap id="userResultMap2" type="user">
        <!--1.匹配user属性-->
        <id column="id" property="id"></id>
        <result column="username" property="username"></result>
        <result column="address" property="address"></result>

        <!--2.匹配user的orderList属性-->
        <collection property="ordersList" ofType="orders">
            <id property="id" column="order_id"></id>
            <result column="number" property="number"></result>
            <result column="createtime" property="createtime"></result>
            <result column="note" property="note"></result>

            <!--集合里嵌套集合-->
            <!--3.匹配Orders里的ordersDetail-->
            <collection property="ordersDetailList" ofType="ordersDetail">
                <id property="id" column="detail_id"></id>
                <result property="items_id" column="items_id"></result>
                <result property="items_num" column="items_num"></result>

                <!--4.配置订单详细的商品信息--><!--集合中嵌套association-->
                <association property="items" javaType="items">
                    <id property="id" column="items_id"></id>
                    <result property="name" column="name"></result>
                    <result property="price" column="price"></result>
                    <result property="detail" column="detail"></result>
                </association>
            </collection>
        </collection>
    </resultMap>
    <select id="findUserAndOrderInfo" resultMap="userResultMap2">
        SELECT
            u.id,
            u.username,
            u.address,
            o.id order_id,
            o.number,
            o.createtime,
            o.note,
            od.id detail_id,
            od.items_id,
            od.items_num,
            it.name,
            it.price,
            it.detail
        FROM
            orders o,
            USER u,
            orderdetail od,
            items it
        WHERE
            o.user_id = u.id
        AND o.id = od.orders_id
        AND od.items_id = it.id
    </select>

第四步:测试

在这里插入图片描述

	@Test
    public void test4(){
    
    
        /*多对多*/
        //通过session获取代理【jdk实现的代理】
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //System.out.println(userMapper);//返回的是一个代理对象
        //查询条件
        List<User> users = userMapper.findUserAndOrderInfo();
        for (User user : users) {
    
    
            System.out.println("用户信息:"+user);
            for (Orders orders : user.getOrdersList()) {
    
    
                System.out.println("订单信息:"+orders);
                for (OrdersDetail ordersDetail : orders.getOrdersDetailList()) {
    
    
                    System.out.println("订单详情:"+ordersDetail+":"+ordersDetail.getItems());
                }
                System.out.println("---------------------------");
            }
        }
        //sqlSession.commit();//增删改记得提交事务
    }

第五步:测试单个用户

  1. UserMapper接口中添加方法
    在这里插入图片描述
  2. 修改UserMapper.xml,上面的resultMap复制一份改成userResultMap3即可
    在这里插入图片描述
  3. 测试
    在这里插入图片描述
	@Test
    public void test5(){
    
    
        /*多对多*/
        //通过session获取代理【jdk实现的代理】
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //System.out.println(userMapper);//返回的是一个代理对象
        //查询条件
        User user = userMapper.findUserAndOrderInfo1(1);
        System.out.println("用户信息:"+user);
        for (Orders orders : user.getOrdersList()) {
    
    
            System.out.println("订单信息:" + orders);
            for (OrdersDetail ordersDetail : orders.getOrdersDetailList()) {
    
    
                System.out.println("订单详情:" + ordersDetail + ":" + ordersDetail.getItems());
            }
            System.out.println("---------------------------");
        }
        //sqlSession.commit();//增删改记得提交事务
    }

总结

  • resultType:将查询结果按照sql列名与pojo属性名的一致性映射到pojo中。
  • resultMap:使用association和collection完成一对一和一对多高级映射(对结果有特殊的映射要求)。
    • association:将关联查询信息映射到一个pojo对象中。
    • collection:将关联查询信息映射到一个list集合中。

第三节 延时加载

  • 延迟加载又叫懒加载,也叫按需加载。也就是说先加载主信息,在需要的时候,再去加载从信息。
  • 在mybatis中,resultMap标签的association标签和collection标签具有延迟加载的功能。

3.1 使用懒加载

第一步:在UserMapper中查看之前写的方法并配置

  • 如果没有就添加上
    在这里插入图片描述
  • 在配置文件中配置
    在这里插入图片描述

第二步:在OrderMapper中写一个方法并配置

在这里插入图片描述

  • 在OrderMapper.xml中配置(通过id查询将数据映射到user中)
    在这里插入图片描述
  • Orders中有user_id属性
    在这里插入图片描述
	<!--懒加载-->
    <resultMap id="lazyLoadingResultMap" type="orders">
        <id column="id" property="id"></id>
        <id column="note" property="note"></id>
        <id column="number" property="number"></id>
        <id column="createtime" property="createtime"></id>
        
        <association property="user" select="com.it.mapper.UserMapper.findUserById" column="user_id"></association>
    </resultMap>
    <select id="findOrderAndByLazyLoading" resultMap="lazyLoadingResultMap">
        SELECT * FROM orders
    </select>

第三步:测试(此时还不是懒加载)

  • 注意观察sql语句的执行与执行结果,执行查询Orders后就立即查询用户user,也就是默认的即时加载
    在这里插入图片描述
	@Test
    public void test6() {
    
    
        /*懒加载*/
        OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
        List<Orders> list = orderMapper.findOrderAndByLazyLoading();
        for (Orders orders : list) {
    
    
            System.out.println("订单信息:"+orders);
            System.out.println("订单所属用户:"+orders.getUser());
        }
    }

第四步:在全局配置文件中配置懒加载

在这里插入图片描述

	<!--配置懒加载-->
    <settings>
        <setting name="lazyLoadingEnabled" value="true"/>
    </settings>
  • 配置完成后再执行一次,对比效果,第一次查询所有的订单,然后再查询id为1用户的订单信息(有2个订单),当使用到id为10的用户的订单信息才去查询加载它(懒加载)
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43414199/article/details/108784802