温锦文欧普厨电及净水器总代理 发表于 2024-10-18 23:27:56

Mybatis高级查询-一对多查询

表先容和表关系说明

新建以下4张表

tb_user:用户表
tb_order:订单表
tb_item:商品表
tb_orderdetail:订单详情表
https://img-blog.csdnimg.cn/img_convert/45f39c8c431666374da00d60893dbdfd.png
【表关系】
1.tb_user和 tb_order表关系
    tb_user《==》tb_order:一对多, 一个人可以下多个订单
    tb_order 《==》 tb_user:一对一,一个订单只能属于一个人
    结论:tb_user和tb_order属于一对多的关系,需要将一方tb_user的主键作为多方tb_order的外键维护关系
2.tb_order 和 tb_item 表关系
    tb_order 《==》 tb_item :一个订单可以有多个商品
    tb_item 《==》 tb_order:一个商品可以在多个订单上
    结论:tb_order和tb_item属于多对多的关系,需要创建中间表tb_orderdetail维护两个表的关系,并且将两张表    的主键作为中间表的外键
一对多查询

【目的】查询id为1的用户及其订单信息
【分析】
一个用户可以有多个订单。
一个订单只能属于一个用户。
用户(1)-----订单(n)
【步骤】
第一步:查询SQL分析;
第二步:添加关联关系;
第三步:编写接口方法;
第四步:编写映射文件;
第五步:测试 【实现】
第一步:需求分析

编写SQL实现查询id为1的用户及其订单信息
查询语句及查询结果:

https://img-blog.csdnimg.cn/img_convert/8d69ff544d41dece39be6a1e8ced0577.png
#查询id为1的用户及其订单信息
select * from tb_user where id=1;
select * from tb_order where user_id=1;

#一对多 内连接查询
select * from tb_user tbu inner join tb_order tbo on tbu.id = tbo.user_id where tbu.id=1;
# 封装数据:关联对象,一个用户关联多个订单User(List<Order> orderList) 说明:一个用户关联多个订单 User(List orderList) ,在User类中界说一个List聚集存储多个订单Order对象。
第二步:添加映射关系

因为一个用户可以拥有多个订单,所以用户和订单是一对多的关系;需要在User类中添加一个List<Order> 属性;
package com.itheima.sh.pojo;

import java.io.Serializable;
import java.util.List;

public class User implements Serializable {

    private Long id;

    // 用户名
    private String userName;

    // 密码
    private String password;

    // 姓名
    private String name;

    // 年龄
    private Integer age;
    //0 女性 1 男性
    private Integer sex;

    //订单
    List<Order> orders;

    public Long getId() {
      return id;
    }

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

    public String getUserName() {
      return userName;
    }

    public void setUserName(String userName) {
      this.userName = userName;
    }

    public String getPassword() {
      return password;
    }

    public void setPassword(String password) {
      this.password = password;
    }

    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }

    public Integer getAge() {
      return age;
    }

    public void setAge(Integer age) {
      this.age = age;
    }

    public Integer getSex() {
      return sex;
    }

    public void setSex(Integer sex) {
      this.sex = sex;
    }

    public List<Order> getOrders() {
      return orders;
    }

    public void setOrders(List<Order> orders) {
      this.orders = orders;
    }

    @Override
    public String toString() {
      return "User{" +
      "id=" + id +
      ", userName='" + userName + '\'' +
      ", password='" + password + '\'' +
      ", name='" + name + '\'' +
      ", age=" + age +
      ", sex=" + sex +
      ", orders=" + orders +
      '}';
    }
} 第三步:编写接口方法

在UserMapper接口中,添加关联查询;
/**
   * 根据用户id查询用户及其订单信息
   * @param id
   * @return
   */
User oneToManyQuery(@Param("id") Long id); 第四步:编写SQL

在UserMapper.xml文件中编写SQL语句完成一对多的关联查询;
说明:
1.一对多使用collection子标签进行关联多方Order
<collection property="类中引用多方的成员变量名" javaType="存放多方容器的类型" ofType="多方类型" autoMapping="true">
</collection>

2.属性:
    1)property="orders" 这里的orders表示User类的成员变量orders
    2)javaType="List" 表示User类的成员变量orders存储的Order对象使用的类型,这里是List 一般不书写
    3) ofType="Order" 表示List集合中存储数据的类型 Order
3.一定要记住这里给user表的id起别名是uid,order表的id起别名是oid.在resultMap标签的id子标签中的column属性值书写对应的uid和oid.

    <!--自定义结果集-->
    <resultMap id="oneToManyResult" type="User" autoMapping="true">
      <!--User的主键-->
      <id column="uid" property="id"/>
      <!--Order关联映射-->
      <!--
            1.一对多使用collection子标签进行关联多方Order
            2.属性:
                1)property="orders" 这里的orders表示User类的成员变量orders
                2)javaType="List" 表示User类的成员变量orders存储的Order对象使用的类型,这里是List,可以不配置
                3) ofType="Order" 表示List集合中存储数据的类型 Order
      -->

      <collection property="orders" javaType="List" ofType="Order" autoMapping="true">
            <!--Order的主键-->
            <id column="oid" property="id" />
      </collection>

    </resultMap>


    <!--根据用户ID查询用户及其订单数据-->
    <select id="oneToManyQuery" resultMap="oneToManyResult">
      SELECT
            tbo.id as oid,
            tbo.order_number,
            tbu.id as uid,
            tbu.user_name,
            tbu.password,
            tbu.name,
            tbu.age,
            tbu.sex
      FROM
            tb_user tbu
            INNER JOIN tb_order tbo ON tbu.id = tbo.user_id
      WHERE
            tbu.id = #{id}
    </select> 第五步:测试

在用户的测试类中
public class MybatisTest01 {
    private static UserMapper mapper = null;

    @BeforeClass
    public static void beforeClass() throws Exception {
      //1.构建SessionFactory
      String resouce = "mybatis-config.xml";
      InputStream is = Resources.getResourceAsStream(resouce);
      SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);
      //2.获取session
      SqlSession sqlSession = build.openSession(true);
      //3.获取接口对象
      mapper = sqlSession.getMapper(UserMapper.class);
    }
    //根据用户ID查询用户及其订单数据
    @Test
    public void oneToManyQuery() {
      User user = mapper.oneToManyQuery(1L);
      System.out.println("user = " + user);
    }
}
https://img-blog.csdnimg.cn/img_convert/6fb97b774c414f8bc70f6854819352b8.png
【小结】

一对多关系配置:
1、在对象中添加映射关系;
2、编写接口方法,编写SQL;
3、编写resultMap处理数据库字段和实体类之间数据的封装;
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Mybatis高级查询-一对多查询