MyBatis学习笔记——关联查询

这篇博客介绍了MyBatis中三种关联查询的实现方式:一对一查询,包括扩展类实现和在Orders类中直接添加User属性的方法;一对多查询,涉及如何获取订单及其详细信息;以及多对多查询,讲解了如何查询用户及他们的多个订单。

关联查询

  • 一对一 是通过在任意一方的主键,引入对方主键作为外键来实现的,就是说主键与外键为同一字段
  • 一对多 是通过在“多”的一方,添加“一”的一方的主键作为外键
  • 多对多 是通过一张中间关系表,引入两张表的主键作为外键,两个主键成为联合主键或使用新的字段作为主键

在这里插入图片描述


  • user和orders:
    User 与orders:一个用户可以创建多个订单,一对多

  • orders和orderdetail:
    Orders 与 orderdetail:一个订单可以包括 多个订单明细,因为一个订单可以购买多个商品,每个商品的购买信息在orderdetail记录,一对多关系

  • orderdetail和items:
    Orderdetail 与 items:多个订单明细只对应一个商品信息,多对一


一对一

需求:

根据商品ID查找定单信息,包括用户名和地址
一个订单对应一个用户

方法一:扩展类实现
  1. 在复杂查询时,单表对应的po类已经不能满足结果集的映射,所以根据需求建立一个扩展类作为resultType的类型

    package com.hf.model;
    
    public class OrdersExt extends Orders {
        private String username;
        private String address;
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
    
        @Override
        public String toString() {
            return "OrdersExt{" +
                    "username='" + username + '\'' +
                    ", address='" + address + '\'' +
                    '}'+super.toString();
        }
    }
    
    
  2. 声明订单接口

    package com.hf.mapper;
    
    import com.hf.model.Orders;
    import com.hf.model.OrdersExt;
    
    public interface OrderMapper {
    
    
        /**
         * 通过id查找
         * @param id
         * @return
         */
        public OrdersExt findOrderById(int id);
    }
    
    
  3. 在OrderMapper.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.hf.mapper.OrderMapper">
        <select id="findOrderById" resultType="ordersExt" parameterType="int">
            SELECT
                o.*,u.username,u.address
            FROM
                orders o ,user u
            WHERE
                u.id = o.user_id AND o.id = #{id}
        </select>
    
    </mapper>
    
  4. 在全局配置文件中加载配置文件

    <mapper resource="com/hf/mapper/OrderMapper.xml"></mapper>
    
  5. 测试

      @Test
        public void test1()
        {
            OrderMapper mapper = session.getMapper(OrderMapper.class);
    
            OrdersExt ordersExt = mapper.findOrderById(3);
    
            System.out.println(ordersExt);
    
        }
    

    在这里插入图片描述

方法二:在Orders类中实现一个User属性
  1. 在Orders类中添加一个User属性,并提供get/set方法
    在这里插入图片描述

  2. 在OrderMapper.java中声明接口方法

    /**
         * 通过id查找
         * @param id
         * @return
         */
        public Orders findOrderById2(int id);
    
  3. 在OrderMapper.xml中配置,使用resultMap

    <!--如果模型里面有模型,使用resultMap-->
    <resultMap id="orderResultMap" type="orders">
        <!--往Orders的模型匹配数据-->
        <id column="id" property="id"></id>
        <result column="note" property="note"></result>
        <result column="number" property="number"></result>
        <result column="createtime" property="createtime"></result>
        <!--往User属性匹配数据-->
        <association property="user" javaType="user">
            <id column="user_id" property="id"></id>
            <result column="username" property="username"></result>
            <result column="address" property="address"></result>
        </association>
    </resultMap>
    
    <select id="findOrderById2" resultMap="orderResultMap" parameterType="int">
        SELECT
            o.*,u.username,u.address
        FROM
            orders o ,user u
        WHERE
            u.id = o.user_id AND o.id = #{id}
    </select>
    
    
  4. 测试

    @Test
        public void test2()
        {
            OrderMapper mapper = session.getMapper(OrderMapper.class);
    
            Orders order = mapper.findOrderById2(3);
    
            System.out.println(order);
    
        }
    

    在这里插入图片描述

一对多

需求:

根据订单id查找订单,用户信息以及订单详细信息
一个订单对应多个订单详细

  1. 定义一个订单详细信息OrderDetail类

    package com.hf.model;
    
    /**
     * 订单详情
     */
    public class OrderDetail {
        private Integer id;//订单详情id
        private Integer itemsId;//商品id
        private Integer itemsNum; //购买数量
    
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public Integer getItemsId() {
            return itemsId;
        }
    
        public void setItemsId(Integer itemsId) {
            this.itemsId = itemsId;
        }
    
        public Integer getItemsNum() {
            return itemsNum;
        }
    
        public void setItemsNum(Integer itemsNum) {
            this.itemsNum = itemsNum;
        }
    
        @Override
        public String toString() {
            return "OrderDetail{" +
                    "id=" + id +
                    ", itemsId=" + itemsId +
                    ", itemsNum=" + itemsNum +
                    '}';
        }
    }
    
    
  2. 在Orders类中声明一个OrderDetail集合,并提供get/set方法
    在这里插入图片描述

  3. 在OrderMapper.java中声明接口方法

    /**
         * 通过id查找
         * @param id
         * @return
         */
        public Orders findOrderById2(int id);
    
  4. 在OrderMapper.xml中配置

    <resultMap id="orderResultMap3" type="orders">
        <!--往Orders的模型匹配数据-->
        <id column="id" property="id"></id>
        <result column="note" property="note"></result>
        <result column="number" property="number"></result>
        <result column="createtime" property="createtime"></result>
        <!--往User属性匹配数据-->
        <association property="user" javaType="user">
            <id column="user_id" property="id"></id>
            <result column="username" property="username"></result>
            <result column="address" property="address"></result>
        </association>
    
        <!--往orders中的orderDetails匹配数据
            注意:集合的类型使用ofType而不是javaType
        -->
        <collection property="orderDetails" ofType="orderDetail">
            <id column="detail_id" property="id"></id>
            <result column="items_id" property="itemsId"></result>
            <result column="items_num" property="itemsNum"></result>
        </collection>
    </resultMap>
    
    <select id="findOrderById3" resultMap="orderResultMap3" parameterType="int">
        SELECT
            o.*,
            u.username,
            u.address,
            od.id detail_id,
            od.items_id,
            od.items_num
        FROM
            orders o,
            user u,
            orderdetail od
        WHERE
            o.user_id = u.id
            AND od.orders_id = o.id
            AND o.id = #{id}
    </select>
    
  5. 测试

    @Test
        public void test3()
        {
            OrderMapper mapper = session.getMapper(OrderMapper.class);
    
            Orders order = mapper.findOrderById3(3);
    
            System.out.println(order);
            System.out.println(order.getUser());
            System.out.println(order.getOrderDetails());
    
        }
    

    在这里插入图片描述

多对多

需求:

查询所有用户及订单

思路

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190820171138609.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjIzNjUzNQ==,size_16,color_FFFFFF,t_70

  1. 定义模型

    package com.hf.model;
    
    import java.io.Serializable;
    import java.util.Date;
    import java.util.List;
    
    
    public class User implements Serializable {
    	private int id;
    	private String username;// 用户姓名
    	private String sex;// 性别
    	private Date birthday;// 生日
    	private String address;// 地址
    
    	/*用户和订单,一对多关系*/
    	private List<Orders> orders;
    
    
    	public User(String username, String sex, Date birthday, String address) {
    		this.username = username;
    		this.sex = sex;
    		this.birthday = birthday;
    		this.address = address;
    	}
    
    	public User() {
    	}
    
    	public int getId() {
    		return id;
    	}
    	public void setId(int id) {
    		this.id = id;
    	}
    	public String getUsername() {
    		return username;
    	}
    	public void setUsername(String username) {
    		this.username = username;
    	}
    	public String getSex() {
    		return sex;
    	}
    	public void setSex(String sex) {
    		this.sex = sex;
    	}
    	public Date getBirthday() {
    		return birthday;
    	}
    	public void setBirthday(Date birthday) {
    		this.birthday = birthday;
    	}
    	public String getAddress() {
    		return address;
    	}
    	public void setAddress(String address) {
    		this.address = address;
    	}
    
    	public List<Orders> getOrders() {
    		return orders;
    	}
    
    	public void setOrders(List<Orders> orders) {
    		this.orders = orders;
    	}
    
    	@Override
    	public String toString() {
    		return "User [id=" + id + ", username=" + username + ", sex=" + sex
    				+ ", birthday=" + birthday + ", address=" + address + "]";
    	}
    }
    
    
    package com.hf.model;
    
    import java.util.Date;
    import java.util.List;
    
    public class Orders{
        private Integer id;
        private Integer user_id;
        private String note;
        private String number;
        private Date createtime;
        private User user;
    
    
        /*一对多数据封装*/
        private List<OrderDetail> orderDetails;
    
    
        public List<OrderDetail> getOrderDetails() {
            return orderDetails;
        }
    
        public void setOrderDetails(List<OrderDetail> orderDetails) {
            this.orderDetails = orderDetails;
        }
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public Integer getUser_id() {
            return user_id;
        }
    
        public void setUser_id(Integer user_id) {
            this.user_id = user_id;
        }
    
        public String getNote() {
            return note;
        }
    
        public void setNote(String note) {
            this.note = note;
        }
    
        public String getNumber() {
            return number;
        }
    
        public void setNumber(String number) {
            this.number = number;
        }
    
        public Date getCreatetime(){
            return createtime;
        }
    
        public void setCreatetime(Date createtime) {
            this.createtime = createtime;
        }
    
    
        @Override
        public String toString() {
            return "Orders{" +
                    "id=" + id +
                    ", user_id=" + user_id +
                    ", note='" + note + '\'' +
                    ", number='" + number + '\'' +
                    ", createtime=" + createtime +
                    '}';
        }
    }
    
    
    package com.hf.model;
    
    /**
     * 订单详情
     */
    public class OrderDetail {
        private Integer id;//订单详情id
        private Integer itemsId;//商品id
        private Integer itemsNum; //购买数量
        private Items items;//商品信息
    
        public Items getItems() {
            return items;
        }
    
        public void setItems(Items items) {
            this.items = items;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public Integer getItemsId() {
            return itemsId;
        }
    
        public void setItemsId(Integer itemsId) {
            this.itemsId = itemsId;
        }
    
        public Integer getItemsNum() {
            return itemsNum;
        }
    
        public void setItemsNum(Integer itemsNum) {
            this.itemsNum = itemsNum;
        }
    
        @Override
        public String toString() {
            return "OrderDetail{" +
                    "id=" + id +
                    ", itemsId=" + itemsId +
                    ", itemsNum=" + itemsNum +
                    '}';
        }
    }
    
    
    package com.hf.model;
    
    public class Items {
        private Integer id;
        private String name;
        private Float price;
        private String detail;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Float getPrice() {
            return price;
        }
    
        public void setPrice(Float price) {
            this.price = price;
        }
    
        public String getDetail() {
            return detail;
        }
    
    
        @Override
        public String toString() {
            return "Items{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", price=" + price +
                    ", detail='" + detail + '\'' +
                    '}';
        }
    
        public void setDetail(String detail) {
            this.detail = detail;
        }
    }
    
    
  2. 在OrderMapper.java中声明接口方法

    /**
         * 查询所有用户及订单
         * @return
         */
        public List<User> findUserAndOrderAll();
    
  3. 在OrderMapper.xml中配置

     <!--===========多对多 查询用户和订单================-->
        <resultMap id="userResultMap" type="user">
            <!--user的属性-->
            <id column="id" property="id"/>
            <result column="username" property="username"/>
            <result column="address" property="address"/>
    
            <!--user里的orders属性-->
            <collection property="orders" ofType="orders">
                <id column="order_id" property="id"/>
                <result column="number" property="number"/>
                <result column="createtime" property="createtime"/>
                <result column="note" property="note"/>
    
    
                <!--嵌套,在orders中为orderDetails赋值-->
                <collection property="orderDetails" ofType="orderDetail">
                    <id column="detail_id" property="id"/>
                    <result column="items_id" property="itemsId"/>
                    <result column="items_num" property="itemsNum"/>
    
    
                    <!--嵌套,在orderDetail中为items赋值-->
                    <association property="items" javaType="items">
                        <id column="items_id" property="id"/>
                        <result column="name" property="name"/>
                        <result column="price" property="price"/>
                        <result column="detail" property="detail"/>
                    </association>
                </collection>
            </collection>
    
        </resultMap>
    
        <select id="findUserAndOrderAll" resultMap="userResultMap">
            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
                user u,
                orders o,
                orderdetail od,
                items it
            WHERE
                o.user_id = u.id
                AND o.id = od.orders_id
                AND od.items_id = it.id
        </select>
    
  4. 测试

     @Test
        public void test4()
        {
            OrderMapper mapper = session.getMapper(OrderMapper.class);
    
            List<User> users = mapper.findUserAndOrderAll();
    
            for (User user : users) {
                System.out.println("用户信息:"+user);
                System.out.println("---------------------------------");
                for (Orders order : user.getOrders()) {
                    System.out.println("订单信息:"+order);
    
                    for (OrderDetail orderDetail : order.getOrderDetails()) {
                        System.out.println("订单详细信息:"+orderDetail +"---商品信息:"+orderDetail.getItems());
                    }
                    System.out.println("---------------------------------");
    
                }
            }
    
        }
    

    在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值