Mybatis高级映射一对多查询

本文目标:以主表(orders订单表)和 另外两个关联表(orderdetail 订单详细表,user 用户表)进行一对多查询。

一、开发准备

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

  1. DROP TABLE IF EXISTS `items`;
  2. DROP TABLE IF EXISTS `orders`;
  3. DROP TABLE IF EXISTS `user`;
  4. DROP TABLE IF EXISTS `orderdetail`;
  5. /*items是商品表*/
  6. CREATE TABLE `items` (
  7.   `id` INT(11) NOT NULL AUTO_INCREMENT,
  8.   `nameVARCHAR(32) NOT NULL COMMENT '商品名称',
  9.   `price` FLOAT(10,1) NOT NULL COMMENT '商品定价',
  10.   `detail` TEXT COMMENT '商品描述',
  11.   `pic` VARCHAR(64) DEFAULT NULL COMMENT '商品图片',
  12.   `createtime` DATETIME NOT NULL COMMENT '生产日期',
  13.   PRIMARY KEY (`id`)
  14. ) ENGINE=INNODB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
  15. /*user是用户表*/
  16. CREATE TABLE `user` (
  17.   `id` INT(11) NOT NULL AUTO_INCREMENT,
  18.   `username` VARCHAR(32) NOT NULL COMMENT '用户名称',
  19.   `birthday` DATE DEFAULT NULL COMMENT '生日',
  20.   `gender` CHAR(1) DEFAULT NULL COMMENT '性别',
  21.   `address` VARCHAR(256) DEFAULT NULL COMMENT '地址',
  22.   PRIMARY KEY (`id`)
  23. ) ENGINE=INNODB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
  24. /*orders是订单表*/
  25. CREATE TABLE `orders` (
  26.   `id` INT(11) NOT NULL AUTO_INCREMENT,
  27.   `user_id` INT(11) NOT NULL COMMENT '下单用户id',
  28.   `number` VARCHAR(32) NOT NULL COMMENT '订单号',
  29.   `createtime` DATETIME NOT NULL COMMENT '创建订单时间',
  30.   `note` VARCHAR(100) DEFAULT NULL COMMENT '备注',
  31.   PRIMARY KEY (`id`),
  32.   KEY `FK_orders_1` (`user_id`),
  33.   CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
  34. ) ENGINE=INNODB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
  35. /*orderdetail是订单明细表*/
  36. DROP TABLE IF EXISTS orderdetail;
  37. CREATE TABLE `orderdetail` (
  38.   `id` INT(11) NOT NULL AUTO_INCREMENT,
  39.   `orders_id` INT(11) NOT NULL COMMENT '订单id',
  40.   `items_id` INT(11) NOT NULL COMMENT '商品id',
  41.   `items_num` INT(11) DEFAULT NULL COMMENT '商品购买数量',
  42.   PRIMARY KEY (`id`),
  43.   KEY `FK_orderdetail_1` (`orders_id`),
  44.   KEY `FK_orderdetail_2` (`items_id`),
  45.   CONSTRAINT `FK_orderdetail_1` FOREIGN KEY (`orders_id`) REFERENCES `orders` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  46.   CONSTRAINT `FK_orderdetail_2` FOREIGN KEY (`items_id`) REFERENCES `items` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
  47. ) ENGINE=INNODB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

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

Mybatis高级映射一对多查询

Mybatis高级映射一对多查询

Mybatis高级映射一对多查询

Mybatis高级映射一对多查询

2、思路分析

Mybatis高级映射一对多查询

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

 首先还是先写sql语句,在写sql语句的时候遵循两点:

  1. 查询的主表是哪个? 订单表
  2. 查询的关联表是哪个? 订单明细表

明确了主表和关联表,下面就可以写sql了,我们在上一节的sql基础上添加订单明细表的关联即可。

  1. <!--查询订单关联查询用户及订单明细-->
  2. <select id="findOrdersAndOrderDetailResultMap" resultMap="OrdersAndOrderDetailResultMap">
  3.     SELECT
  4.         orders.*,
  5.         user.username,
  6.         user.gender,
  7.         user.address,
  8.         orderdetail.id orderdetail_id,
  9.         orderdetail.items_id,
  10.         orderdetail.items_num,
  11.         orderdetail.orders_id
  12.     FROM
  13.         orders,
  14.         user,
  15.         orderdetail
  16.     WHERE orders.user_id=user.id AND orders.id = orderdetail.orders_id
  17. </select>

这样我们就查询出了订单表中的所有字段,user表和orderdetail表的部分字段,当然也可以查询所有字段,这个根据具体需求来定。看一下查询结果:

Mybatis高级映射一对多查询

 

二、代码实现

1、新建三个持久类

① User.java

  1. package com.liuyanzhao.mybatis.po;
  2. import java.util.Date;
  3. /**
  4.  * 用户的持久类
  5.  */
  6. public class User {
  7.     private int id; //编号
  8.     private String username; //用户名
  9.     private String gender; //性别
  10.     private Date birthday; //生日
  11.     private String address; //地址
  12.     public int getId() {
  13.         return id;
  14.     }
  15.     public void setId(int id) {
  16.         this.id = id;
  17.     }
  18.     public String getUsername() {
  19.         return username;
  20.     }
  21.     public void setUsername(String username) {
  22.         this.username = username;
  23.     }
  24.     public String getGender() {
  25.         return gender;
  26.     }
  27.     public void setGender(String gender) {
  28.         this.gender = gender;
  29.     }
  30.     public Date getBirthday() {
  31.         return birthday;
  32.     }
  33.     public void setBirthday(Date birthday) {
  34.         this.birthday = birthday;
  35.     }
  36.     public String getAddress() {
  37.         return address;
  38.     }
  39.     public void setAddress(String address) {
  40.         this.address = address;
  41.     }
  42. }

 

② Orderdetail.java

  1. package com.liuyanzhao.mybatis.po;
  2. /**
  3.  * 订单明细的持久类
  4.  */
  5. public class Orderdetail {
  6.     private int id;
  7.     private int ordersId;
  8.     private int itemsId;
  9.     private int itemsNum;
  10.     public int getId() {
  11.         return id;
  12.     }
  13.     public void setId(int id) {
  14.         this.id = id;
  15.     }
  16.     public int getOrdersId() {
  17.         return ordersId;
  18.     }
  19.     public void setOrdersId(int ordersId) {
  20.         this.ordersId = ordersId;
  21.     }
  22.     public int getItemsId() {
  23.         return itemsId;
  24.     }
  25.     public void setItemsId(int itemsId) {
  26.         this.itemsId = itemsId;
  27.     }
  28.     public int getItemsNum() {
  29.         return itemsNum;
  30.     }
  31.     public void setItemsNum(int itemsNum) {
  32.         this.itemsNum = itemsNum;
  33.     }
  34. }

 

③ Orders.java

  1. package com.liuyanzhao.mybatis.po;
  2. import java.util.Date;
  3. import java.util.List;
  4. /**
  5.  * 订单的持久类和扩展类
  6.  */
  7. public class Orders {
  8.     private int id;
  9.     private int userId;
  10.     private String number;
  11.     private Date createTime;
  12.     private String note;
  13.     //用户信息
  14.     private User user;
  15.     //订单明细
  16.     private List<Orderdetail> orderdetails;
  17.     public User getUser() {
  18.         return user;
  19.     }
  20.     public void setUser(User user) {
  21.         this.user = user;
  22.     }
  23.     public List<Orderdetail> getOrderdetails() {
  24.         return orderdetails;
  25.     }
  26.     public void setOrderdetails(List<Orderdetail> orderdetails) {
  27.         this.orderdetails = orderdetails;
  28.     }
  29.     public int getId() {
  30.         return id;
  31.     }
  32.     public void setId(int id) {
  33.         this.id = id;
  34.     }
  35.     public int getUserId() {
  36.         return userId;
  37.     }
  38.     public void setUserId(int userId) {
  39.         this.userId = userId;
  40.     }
  41.     public String getNumber() {
  42.         return number;
  43.     }
  44.     public void setNumber(String number) {
  45.         this.number = number;
  46.     }
  47.     public Date getCreateTime() {
  48.         return createTime;
  49.     }
  50.     public void setCreateTime(Date createTime) {
  51.         this.createTime = createTime;
  52.     }
  53.     public String getNote() {
  54.         return note;
  55.     }
  56.     public void setNote(String note) {
  57.         this.note = note;
  58.     }
  59. }

注意:我们的orders 表作为主表,orders类当然需要扩展其他关联表的属性

 

2、OrdersMapperCustom.java

  1. package com.liuyanzhao.mybatis.mapper;
  2. import com.liuyanzhao.mybatis.po.Orders;
  3. import java.util.List;
  4. /**
  5.  * 订单 mapper
  6.  */
  7. public interface OrdersMapperCustom {
  8.     //查询订单(关联用户)及订单明细
  9.     public List<Orders> findOrdersAndOrderDetailResultMap() throws Exception;
  10. }

 

3、OrdersMapperCustom.xml  映射文件

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3.         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4.         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.liuyanzhao.mybatis.mapper.OrdersMapperCustom">
  6.     <!--订单和订单明细的resultMap-->
  7.     <resultMap id="OrdersAndOrderDetailResultMap" type="com.liuyanzhao.mybatis.po.Orders">
  8.         <!--订单信息-->
  9.         <!--
  10.             id:指定查询到的唯一标识符
  11.             column:订单信息的唯一表示列
  12.             property:订单信息的唯一标识列所映射到Orders中哪个属性
  13.         -->
  14.         <id column="id" property="id"></id>
  15.         <result column="user_id" property="userId"></result>
  16.         <result column="number" property="number"></result>
  17.         <result column="createtime" property="createTime"></result>
  18.         <result column="note" property="note"></result>
  19.         <!--用户信息-->
  20.         <!--
  21.             association;用于映射关联查询单个对象的信息
  22.             property:要将关联查询的用户信息映射到orders中的哪个属性
  23.         -->
  24.         <association property="user" javaType="com.liuyanzhao.mybatis.po.User">
  25.             <id column="user_id" property="id"></id>
  26.             <result column="username" property="username"></result>
  27.             <result column="gender" property="gender"></result>
  28.             <result column="address" property="address"></result>
  29.         </association>
  30.         <!--订单明细信息-->
  31.         <!--
  32.             一个订单中关联查询多条明细,要是用collection进行映射
  33.             collection:对关联查询到多条记录映射到集合对象中
  34.             property:将关联查询到的多条记录映射到Orders哪个属性
  35.             ofType:指定映射到集合属性中pojo的类型
  36.         -->
  37.         <collection property="orderdetails" ofType="com.liuyanzhao.mybatis.po.Orderdetail">
  38.             <id column="orderdetail_id" property="id"></id>
  39.             <result column="items_id" property="itemsId"></result>
  40.             <result column="items_num" property="itemsNum"></result>
  41.             <result column="orders_id" property="ordersId"></result>
  42.         </collection>
  43.     </resultMap>
  44.     <!--查询订单关联查询用户及订单明细-->
  45.     <select id="findOrdersAndOrderDetailResultMap" resultMap="OrdersAndOrderDetailResultMap">
  46.         SELECT
  47.             orders.*,
  48.             user.username,
  49.             user.gender,
  50.             user.address,
  51.             orderdetail.id orderdetail_id,
  52.             orderdetail.items_id,
  53.             orderdetail.items_num,
  54.             orderdetail.orders_id
  55.         FROM
  56.             orders,
  57.             user,
  58.             orderdetail
  59.         WHERE orders.user_id=user.id AND orders.id = orderdetail.orders_id
  60.     </select>
  61. </mapper>

注意:

  • <resultMap>的 id 是一个唯一标识符;type 相当于 resultType,表示查询的返回值类型。
  • <select>标签的 resultMap 要和 <resultMap>标签的 id 一致
  • association 和collection 两个标签的区别:Mybatis高级映射一对多查询

 

 

4、测试类 OrdersMapperCustomTest.java

  1. package com.liuyanzhao.mybatis.test;
  2. import com.liuyanzhao.mybatis.mapper.OrdersMapperCustom;
  3. import com.liuyanzhao.mybatis.po.Orders;
  4. import org.apache.ibatis.io.Resources;
  5. import org.apache.ibatis.session.SqlSession;
  6. import org.apache.ibatis.session.SqlSessionFactory;
  7. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  8. import org.junit.Before;
  9. import org.junit.Test;
  10. import java.io.InputStream;
  11. import java.util.List;
  12. /**
  13.  * Created by Liu_Yanzhao on 2017/8/12.
  14.  */
  15. public class OrdersMapperCustomTest {
  16.     SqlSessionFactory sqlSessionFactory;
  17.     @Before
  18.     public void setUp() throws Exception {
  19.         String resource = "Configuration.xml";
  20.         InputStream inputStream = Resources.getResourceAsStream(resource);
  21.         sqlSessionFactory = new SqlSessionFactoryBuilder()
  22.             .build(inputStream);
  23.     }
  24.     @Test
  25.     public void testFindOrdersAndOrderDetailResultMap() throws Exception {
  26.         SqlSession sqlSession = sqlSessionFactory.openSession();
  27.         //创建代理对象
  28.         OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
  29.         //调用mapper对象
  30.         List<Orders> list = ordersMapperCustom.findOrdersAndOrderDetailResultMap();
  31.         System.out.println(list);
  32.         //释放资源
  33.         sqlSession.close();
  34.     }
  35. }

 

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

 

参考:传智播客视频

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

 

  • 微信
  • 赶快加我聊天吧
  • weinxin
  • 博客/Java交流群
  • 资源分享,问题解决,技术交流。群号:590480292
  • weinxin
广告也精彩
言曌
广告也精彩

发表评论

:?::razz::sad::evil::!::smile::oops::grin::eek::shock::???::cool::lol::mad::twisted::roll::wink::idea::arrow::neutral::cry::mrgreen: