Mybatis高级映射多对多查询

一、开发准备

1、新建数据表(四张表)和添加测试数据

DROP TABLE IF EXISTS `items`;

DROP TABLE IF EXISTS `orders`;

DROP TABLE IF EXISTS `user`;

DROP TABLE IF EXISTS `orderdetail`;

/*items是商品表*/

CREATE TABLE `items` (

  `id` INT(11) NOT NULL AUTO_INCREMENT,

  `name` VARCHAR(32) NOT NULL COMMENT '商品名称',

  `price` FLOAT(10,1) NOT NULL COMMENT '商品定价',

  `detail` TEXT COMMENT '商品描述',

  `pic` VARCHAR(64) DEFAULT NULL COMMENT '商品图片',

  `createtime` DATETIME NOT NULL COMMENT '生产日期',

  PRIMARY KEY (`id`)

) ENGINE=INNODB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

/*user是用户表*/

CREATE TABLE `user` (

  `id` INT(11) NOT NULL AUTO_INCREMENT,

  `username` VARCHAR(32) NOT NULL COMMENT '用户名称',

  `birthday` DATE DEFAULT NULL COMMENT '生日',

  `gender` CHAR(1) DEFAULT NULL COMMENT '性别',

  `address` VARCHAR(256) DEFAULT NULL COMMENT '地址',

  PRIMARY KEY (`id`)

) ENGINE=INNODB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;

/*orders是订单表*/

CREATE TABLE `orders` (

  `id` INT(11) NOT NULL AUTO_INCREMENT,

  `user_id` INT(11) NOT NULL COMMENT '下单用户id',

  `number` VARCHAR(32) NOT NULL COMMENT '订单号',

  `createtime` DATETIME NOT NULL COMMENT '创建订单时间',

  `note` VARCHAR(100) DEFAULT NULL COMMENT '备注',

  PRIMARY KEY (`id`),

  KEY `FK_orders_1` (`user_id`),

  CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION

) ENGINE=INNODB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

/*orderdetail是订单明细表*/

DROP TABLE IF EXISTS orderdetail;

CREATE TABLE `orderdetail` (

  `id` INT(11) NOT NULL AUTO_INCREMENT,

  `orders_id` INT(11) NOT NULL COMMENT '订单id',

  `items_id` INT(11) NOT NULL COMMENT '商品id',

  `items_num` INT(11) DEFAULT NULL COMMENT '商品购买数量',

  PRIMARY KEY (`id`),

  KEY `FK_orderdetail_1` (`orders_id`),

  KEY `FK_orderdetail_2` (`items_id`),

  CONSTRAINT `FK_orderdetail_1` FOREIGN KEY (`orders_id`) REFERENCES `orders` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,

  CONSTRAINT `FK_orderdetail_2` FOREIGN KEY (`items_id`) REFERENCES `items` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION

) ENGINE=INNODB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

为了测试,我这里随便填了些数据

Mybatis高级映射多对多查询

Mybatis高级映射多对多查询

Mybatis高级映射多对多查询

Mybatis高级映射多对多查询

2、思路分析

Mybatis高级映射多对多查询

订单项和订单明细是一对多的关系,所以本文主要来查询订单表,然后关联订单明细表,这样就有一对多的问题出来了。

因为多对多比较复杂,总公共有四张表,我们先来分析一下思路:

1、将用户信息映射到User中;

2、在User类中添加订单列表属性List<Orders>ordersList,将用户创建的订单映射到ordersList中;

3、在Orders中添加订单明细列表属性List<OrderDetail>orderDetails,将订单的明细映射到orderDetails中;

4、在OrderDetail中添加Items属性,将订单明细所对应的商品映射到Items中。

经过这样分析后,感觉虽然有点复杂,但是好像不是很难的样子,映射的方法也跟前面的一样,只不过这里表有点多,关系有点复杂。下面来写映射文件:

<select id="findUserAndItemsResultMap" resultMap="UserAndItemsResultMap">

    SELECT

      orders.*,

      user.`username`,

      user.`sex`,

      user.`address`,

      orderdetail.`id` orderdetail_id,

      orderdetail.`items_id`,

      orderdetail.`items_num`,

      orderdetail.`orders_id`,

      items.`name` items_name,

      items.`detail` items_detail,

      items.`price` items_price

    FROM

      orders,

      USER,

      orderdetail,

      items

    WHERE orders.`user_id`=user.`id` AND orders.`id` = orderdetail.`orders_id` AND orderdetail.`items_id`=items.`id`

</select>

我们先看一下查询结果:

Mybatis高级映射多对多查询

二、代码实现

1、四个持久化类

① User.java

package com.liuyanzhao.mybatis.po;

import java.util.Date;

import java.util.List;

/**

 * 用户的持久类

 */

public class User {

    private int id; //编号

    private String username; //用户名

    private String gender; //性别

    private Date birthday; //生日

    private String address; //地址

    public List<Orders> getOrdersList() {

        return ordersList;

    }

    public void setOrdersList(List<Orders> ordersList) {

        this.ordersList = ordersList;

    }

    //用户创建的订单列表

    private List<Orders> ordersList;

    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 getGender() {

        return gender;

    }

    public void setGender(String gender) {

        this.gender = gender;

    }

    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;

    }

}

注意:需要在用户表中加入 订单列表

② Items.java

package com.liuyanzhao.mybatis.po;

import java.util.Date;

/**

 * 商品的持久类

 */

public class Items {

    private int id;

    private String name;

    private double price;

    private String detail;

    private String pic;

    private Date createTime;

    public int getId() {

        return id;

    }

    public void setId(int id) {

        this.id = id;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public double getPrice() {

        return price;

    }

    public void setPrice(double price) {

        this.price = price;

    }

    public String getDetail() {

        return detail;

    }

    public void setDetail(String detail) {

        this.detail = detail;

    }

    public String getPic() {

        return pic;

    }

    public void setPic(String pic) {

        this.pic = pic;

    }

    public Date getCreateTime() {

        return createTime;

    }

    public void setCreateTime(Date createTime) {

        this.createTime = createTime;

    }

}

③ Orders.java

package com.liuyanzhao.mybatis.po;

import java.util.Date;

import java.util.List;

/**

 * 订单的持久类和扩展类

 */

public class Orders {

    private int id;

    private int userId;

    private String number;

    private Date createTime;

    private String note;

    //订单明细

    private List<Orderdetail> orderdetails;

    public List<Orderdetail> getOrderdetails() {

        return orderdetails;

    }

    public void setOrderdetails(List<Orderdetail> orderdetails) {

        this.orderdetails = orderdetails;

    }

    public int getId() {

        return id;

    }

    public void setId(int id) {

        this.id = id;

    }

    public int getUserId() {

        return userId;

    }

    public void setUserId(int userId) {

        this.userId = userId;

    }

    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;

    }

    public String getNote() {

        return note;

    }

    public void setNote(String note) {

        this.note = note;

    }

}

注意:订单列表中,需要订单的详细信息,不需要用户信息

④ Orderdetail.java

package com.liuyanzhao.mybatis.po;

/**

 * 订单明细的持久类

 */

public class Orderdetail {

    private int id;

    private int ordersId;

    private int itemsId;

    private int itemsNum;

    //明细对应的商品信息

    private Items items;

    public Items getItems() {

        return items;

    }

    public void setItems(Items items) {

        this.items = items;

    }

    public int getId() {

        return id;

    }

    public void setId(int id) {

        this.id = id;

    }

    public int getOrdersId() {

        return ordersId;

    }

    public void setOrdersId(int ordersId) {

        this.ordersId = ordersId;

    }

    public int getItemsId() {

        return itemsId;

    }

    public void setItemsId(int itemsId) {

        this.itemsId = itemsId;

    }

    public int getItemsNum() {

        return itemsNum;

    }

    public void setItemsNum(int itemsNum) {

        this.itemsNum = itemsNum;

    }

}

注意:订单明细里,需要 商品信息

2、订单代理 即mapper.java

OrdersMapperCustom.java

package com.liuyanzhao.mybatis.mapper;

import com.liuyanzhao.mybatis.po.User;

import java.util.List;

/**

 * 订单 mapper

 */

public interface OrdersMapperCustom {

    //查询用户购买的商品信息

    public List<User> findUserAndItemsResultMap() throws Exception;

}

3、OrdersMapperCustom.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.liuyanzhao.mybatis.mapper.OrdersMapperCustom">

    <!--查询用户购买的商品-->

    <resultMap id="UserAndItemsResultMap" type="com.liuyanzhao.mybatis.po.User">

        <!--用户信息-->

        <id column="user_id" property="id"></id>

        <result column="username" property="username"></result>

        <result column="gender" property="gender"></result>

        <result column="address" property="address"></result>

        <!--订单信息-->

        <!--一个用户可以对应多个订单,故使用collection映射-->

        <collection property="ordersList" ofType="com.liuyanzhao.mybatis.po.Orders">

            <id column="id" property="id"></id>

            <result column="user_id" property="userId"></result>

            <result column="number" property="number"></result>

            <result column="createtime" property="createTime"></result>

            <result column="node" property="node"></result>

            <!--订单明细-->

            <!--一个订单包括多个明细,故使用collection-->

            <collection property="orderdetails" ofType="com.liuyanzhao.mybatis.po.Orderdetail">

                <id column="orderdetail_id" property="id"></id>

                <result column="items_id" property="itemsId"></result>

                <result column="items_num" property="itemsNum"></result>

                <result column="orders_id" property="ordersId"></result>

                <!--商品信息-->

                <!--一个订单明细对应一个商品-->

                <association property="items" javaType="com.liuyanzhao.mybatis.po.Items">

                    <id column="items_id" property="id"></id>

                    <result column="items_name" property="name"></result>

                    <result column="items_price" property="price"></result>

                    <result column="items_detail" property="detail"></result>

                </association>

            </collection>

        </collection>

    </resultMap>

    <select id="findUserAndItemsResultMap" resultMap="UserAndItemsResultMap">

        SELECT

        orders.*,

        user.username,

        user.gender,

        user.address,

        orderdetail.id orderdetail_id,

        orderdetail.items_id,

        orderdetail.items_num,

        orderdetail.orders_id,

        items.name items_name,

        items.detail items_detail,

        items.price items_price

        FROM

        orders,

        user,

        orderdetail,

        items

        WHERE orders.user_id=user.id AND orders.id = orderdetail.orders_id AND orderdetail.items_id=items.id

    </select>

</mapper>

4、测试类 OrderMapperCustomTest.java

package com.liuyanzhao.mybatis.test;

import com.liuyanzhao.mybatis.mapper.OrdersMapperCustom;

import com.liuyanzhao.mybatis.po.User;

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.Before;

import org.junit.Test;

import java.io.InputStream;

import java.util.List;

/**

 * Created by Liu_Yanzhao on 2017/8/12.

 */

public class OrderMapperCustomTest {

    SqlSessionFactory sqlSessionFactory;

    @Before

    public void setUp() throws Exception {

        String resource = "Configuration.xml";

        InputStream inputStream = Resources.getResourceAsStream(resource);

        sqlSessionFactory = new SqlSessionFactoryBuilder()

            .build(inputStream);

    }

    @Test

    public void testFindUserAndItemsResultMap() throws Exception {

        SqlSession sqlSession = sqlSessionFactory.openSession();

        //创建代理对象

        OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);

        //调用mapper对象

        List<User> list = ordersMapperCustom.findUserAndItemsResultMap();

        System.out.println(list);

        //释放资源

        sqlSession.close();

    }

}

还有其他文件就不补充了,如 mybatis 全局配置文件

小结

这样多对多的映射就搞定了。不过还有个问题,就是这里多对多的查询会把所有关联的表的信息都查询出来,然后放到pojo中的对应的List或者某个类中,所以即使我只查了个用户信息,但是这个用户里包含了订单,订单项,商品等信息,感觉装的有点多,好像有时候并不需要这么多冗余的数据出来,但是如果用resultType的话查询出来的字段必须对应pojo中的属性,如果有List等,需要手动装入才行。所以下面总结一下对于这种查询数据比较多的时候,resultType和resultMap各有什么作用?

  1. 比如我们只需要将查询用户购买的商品信息明细清单(如用户名、用户地址、购买商品名称、购买商品时间、购买商品数量),那么我们完全不需要其他的信息,这个时候就没必要使用resultMap将所有的信息都搞出来,我们可以自己定义一个pojo,包含我们需要的字段即可,然后查询语句只查询我们需要的字段,这样使用resultType会方便很多。
  2. 如果我们需要查询该用户的所有详细信息,比如用户点击该用户或者鼠标放上去,会出来跟该用户相关的订单啊,订单明细啊,商品啊之类的,然后我们要点进去看下详细情况的时候,那就需要使用resultMap了,必须将所有信息都装到这个User中,然后具体啥信息再从User中取,很好理解。
  3. 总结一点:使用resultMap是针对那些对查询结果映射有特殊要求的功能,,比如特殊要求映射成list中包括多个list。否则使用resultType比较直接。

到这里,mybatis的多对多映射就总结完了。 

参考:传智播客视频

本文链接:https://liuyanzhao.com/5858.html

猜你喜欢

转载自blog.csdn.net/HXNLYW/article/details/82912175