>以订单商品数据模型为例子:

存在以下四张表,用户表user,用户订单表orders,订单明细表orderdetail,商品表items。四张表之间的关系如下图所示:

下面给出四张表结构的详细定义,出于演示,每张表仅定义少量字段:

用户表:user

列名

数据类型

是否为空

主键

外键

注释

user_id

varchar2(40)

用户主键

user_name

varchar2(40)

用户名

user_pass

varchar2(20)

用户密码

cname

varchar2(20)

昵称

user_img

varchar2(100)

用户头像

订单表:orders

列名

数据类型

是否为空

主键

外键

注释

order_id

varchar2(40)

订单主键

user_id

varchar2(40)

用户外键

numer

varchar2(20)

订单号

order_date

date

订单日期

payment

char(1)

是否付款

订单明细表:orderdetail

列名

数据类型

是否为空

主键

外键

注释

detail_id

varchar2(40)

订单明细主键

order_num

varchar2(40)

订单号

item_id

varchar2(20)

商品外键

buy_num

int

购买数量

商品表:items

列名

数据类型

是否为空

主键

外键

注释

item_id

varchar2(40)

商品主键

item_name

varchar2(40)

商品名称

price

double

商品价格

description

varchar2(50)

商品描述

item_img

varchar2(100)

用户图片

> 一对一关联查询

使用mybatis实现一对一关联查询,操作内容为:订单信息查询,并关联查询创建订单的用户的信息。对于返回查询结果信息可以由resultType或resultMap实现。

resultType实现:

去写一个拓展bean作为输出映射:写一个UserBean,继承User表,将Order表中的字段再写一遍;

缺陷:Order表中的字段写了两遍,做了重复性的工作;

resultMap实现:

上例中使用resultType的实现,再进行关联查询时,对于关联表中的字段只取出几列而已,那么在开发时可以选择一个较多的列POJO对象为基础进行扩展,例如A表与B表进行关联查询,A表查询所有列,B表查询几列,那就需要以A表对应的POJO对象为基础进行扩展。即:class QueryABean extends A 。

但是如果在进行关联查询时,几乎两个表中所有的列都被当做查询结果,那么在扩展类中再定义另外一个表中所有的列,显然不是很合适了,这种情况下最常见的方式,就是把另外一个表所对应的POJO对象组合进来,这时使用mybatis进行输出映射就只能使用resultMap元素了,这就是resultMap的高级使用。

(1)定义Order类、组合类:

package com.langsin.pojo;public class Orders {private Integer orderId;private Integer userId;private String orderNum;private String orderDate;private String payment;public Integer getOrderId() {return orderId;}public void setOrderId(Integer orderId) {this.orderId = orderId;}public Integer getUserId() {return userId;}public void setUserId(Integer userId) {this.userId = userId;}public String getOrderNum() {return orderNum;}public void setOrderNum(String orderNum) {this.orderNum = orderNum;}public String getOrderDate() {return orderDate;}public void setOrderDate(String orderDate) {this.orderDate = orderDate;}public String getPayment() {return payment;}public void setPayment(String payment) {this.payment = payment;}}

这里不采用User中所有的字段再写一遍,而是采用组合的方式将User对象加进来;

package com.langsin.pojo;public class OrderBean extends Orders {private User user=null;public User getUser() {return user;}public void setUser(User user) {this.user = user;}}

(2)Mapper配置文件:

注:在之前将User中所有的字段再写一遍的情况下,我们使用resultMap时,只需要将表中的列名与pojo中不对应的部分关联起来即可,名字相同的会自动映射。

但在组合的方式将User对象加进来的情况,所有的列都要与pojo进行关联,即使名称一致。

<resultMap type="orderBean" id="orderUserMap"><id column="order_id" property="orderId"/><result column="user_id" property="userId"/><result column="order_num" property="orderNum"/><result column="order_date" property="orderDate"/><result column="payment" property="payment"/><!-- Mybatis实现一对一关联映射使用association --><!-- 配置映射的关联的用户的信息,association用于映射关联查询的单个对象的信息property属性:要将关联查询的对象映射到拓展类——OrderBean的那个属性中去javaType属性:要将关联查询的信息映射到哪个Java类中--><association property="user" javaType="user"><id column="user_id" property="userId"/><result column="user_name" property="userName"/><result column="role_code" property="roleCode"/><result column="user_pass" property="password"/><result column="is_login" property="isLogin"/><result column="cname" property="cname"/><result column="telphone" property="telphone"/><result column="address" property="address"/></association></resultMap><select id="queryOrderUser" parameterType="Integer" resultMap="orderUserMap">select o.*,u.* from orders o join user u on o.user_id=u.user_idwhere o.order_id=#{value}</select>

(3)Mapper接口

public interface UserMapper {public OrderBean queryOrderUser(Integer orderId) throws Exception;
}

(4)测试类

@Testpublic void queryOrderUser() throws Exception{Integer orderId=1111;UserMapper mapper=session.getMapper(UserMapper.class);OrderBean orderuser = mapper.queryOrderUser(orderId);System.out.println(orderuser);session.close();}

>一对多关联查询

使用mybatis实现一对多关联查询,操作内容为:查询订单表并关联查询订单明细表。在没有使用框架时,针对于这种情况,一般我们都是service层进行业务处理,首先组装一个订单扩展类,在订单扩展类中定义一个List集合来存放此订单所对应的订单明细。即:先调用dao层查询订单表,然后再根据订单表与订单明细表的主外键关联字段,再调用订单明细的dao再查询订单明细,最终完成数据组装。

通过mybatis框架collection集合,可以很轻松的完成此项工作。

(1)定义订单明细、订单明细组合类

package com.langsin.pojo;public class OrderDetail {private Integer detailId;private String orderNum;private String itemId;private String buyNum;private Integer orderId;public Integer getDetailId() {return detailId;}public void setDetailId(Integer detailId) {this.detailId = detailId;}public String getOrderNum() {return orderNum;}public void setOrderNum(String orderNum) {this.orderNum = orderNum;}public String getItemId() {return itemId;}public void setItemId(String itemId) {this.itemId = itemId;}public String getBuyNum() {return buyNum;}public void setBuyNum(String buyNum) {this.buyNum = buyNum;}public Integer getOrderId() {return orderId;}public void setOrderId(Integer orderId) {this.orderId = orderId;}@Overridepublic String toString() {StringBuilder builder = new StringBuilder();builder.append("OrderDetail [detailId=").append(detailId).append(", orderNum=").append(orderNum).append(", itemId=").append(itemId).append(", buyNum=").append(buyNum).append(", orderId=").append(orderId).append("]");return builder.toString();}}

订单明细与商品是一对一的关系,组合单个对象:

package com.langsin.pojo;public class DetailBean extends OrderDetail {Items item = null;public Items getItem() {return item;}public void setItem(Items item) {this.item = item;}@Overridepublic String toString() {StringBuilder builder = new StringBuilder();builder.append("DetailBean [item=").append(item).append(", toString()=").append(super.toString()).append("]");return builder.toString();}}

订单与订单明细组合类中由于是存放一对多的查询结果,使用集合:

package com.langsin.pojo;import java.util.List;public class OrderList extends Orders {
private List<DetailBean> detailList=null;public List<DetailBean> getDetailList() {return detailList;
}public void setDetailList(List<DetailBean> detailList) {this.detailList = detailList;
}}

(2)Mapper配置文件(collection与association可以嵌套)

<resultMap type="orderList" id="orderListMap">
<id column="order_id" property="orderId"/>
<result column="user_id" property="userId"/>
<result column="order_num" property="orderNum"/>
<result column="order_date" property="orderDate"/>
<result column="payment" property="payment"/>
<!-- Mybatis实现一对多关联映射使用collection -->
<!--
配置映射多条记录的信息,使用collection集合
property属性:对关联查询到的多条记录映射到OrderList中的哪个集合
ofType属性:指定映射到集合中的POJO类型-->
<collection property="detailList" ofType="DetailBean">
<id column="detail_id" property="detailId"/>
<result column="order_num" property="orderNum"/>
<result column="item_id" property="itemId"/>
<result column="buy_num" property="buyNum"/>
<result column="order_id" property="orderId"/>
<association property="item" javaType="items">
<id column="item_id" property="itemId"/>
<result column="item_name" property="itemName"/>
<result column="price" property="price"/>
</association>
</collection>
</resultMap>
<select id="queryOrderList" parameterType="Integer" resultMap="orderListMap">
select orders.*,orderdetail.* from orders join orderdetail on orders.order_id=orderdetail.order_id
where orders.order_id=#{value}
</select><select id="queryOrderList" parameterType="Integer" resultMap="orderListMap">
select orders.*,orderdetail.* from orders join orderdetail on orders.order_id=orderdetail.order_id
where orders.order_id=#{value}
</select>

(3)Mapper接口

public interface UserMapper {public OrderList queryOrderList(Integer orderId)throws Exception;
}

(4)测试类

@Testpublic void queryOrderList() throws Exception{ Integer orderId=1111;UserMapper mapper=session.getMapper(UserMapper.class);OrderList orderList = mapper.queryOrderList(orderId);System.out.println(orderList);List<DetailBean> detailList = orderList.getDetailList();for (DetailBean detailBean : detailList) {System.out.println(detailBean);}session.close();}

>多对多关联查询(实质上还是association和collocation的相互嵌套)

(1)定义pojo,pojo组合类

package com.langsin.pojo;import java.util.List;public class UserOrderList extends User {/*** 已经继承User,包含所有用户信息 * 还需要订单的集合,这个订单元素本身(也就是泛型类型)又应该是包含订单本身和对应明细和商品的集合*/List<OrderList> orderlist = null;public List<OrderList> getOrderlist() {return orderlist;}public void setOrderlist(List<OrderList> orderlist) {this.orderlist = orderlist;}}

(2)Mapper配置

<!-- 完成多对多关联查询 --><resultMap type="userOrderList" id="UserOrderDetailItemMap"><id column="user_id" property="userId"/><result column="user_name" property="userName"/><result column="role_code" property="roleCode"/><result column="user_pass" property="password"/><result column="is_login" property="isLogin"/><result column="cname" property="cname"/><result column="telphone" property="telphone"/><result column="address" property="address"/><collection property="orderlist" ofType="orderList"><id column="order_id" property="orderId"/><result column="user_id" property="userId"/><result column="order_num" property="orderNum"/><result column="order_date" property="orderDate"/><result column="payment" property="payment"/><collection property="detailList" ofType="DetailBean"><id column="detail_id" property="detailId"/><result column="order_num" property="orderNum"/><result column="item_id" property="itemId"/><result column="buy_num" property="buyNum"/><result column="order_id" property="orderId"/><association property="item" javaType="items"><id column="item_id" property="itemId"/><result column="item_name" property="itemName"/><result column="price" property="price"/></association></collection></collection></resultMap><select id="queryUserOrderDetailItem" parameterType="Integer" resultMap="UserOrderDetailItemMap">select `user`.*,orders.*,orderdetail.*,items.* FROM `user`JOIN orders ON `user`.user_id=orders.user_idJOIN orderdetail ON orders.order_id=orderdetail.order_idJOIN items ON orderdetail.item_id=items.item_idWHERE `user`.user_id=#{value};</select>

(3)Mapper接口

public interface UserMapper {public UserOrderList queryUserOrderDetailItem(Integer orderId)throws Exception;
}

(4)测试类

@Testpublic void queryUserOrderDetailItem() throws Exception{   Integer userId=2;UserMapper mapper=session.getMapper(UserMapper.class);UserOrderList userOrderList = mapper.queryUserOrderDetailItem(userId);System.out.println("---用户信息---");System.out.println(userOrderList);System.out.println("-----------------------------------");List<OrderList> orderList = userOrderList.getOrderlist();for (OrderList orderlist : orderList) {System.out.println("订单信息:");System.out.println(orderlist);List<DetailBean> detailList = orderlist.getDetailList();for (DetailBean detailBean : detailList) {System.out.println("明细和商品:");System.out.println(detailBean);}System.out.println("-----------------------------------");}session.close();}

测试debug结果:

---用户信息---
User [userId=2, userName=lisi, password=123789, roleCode=admin, cname=weiwei, telphone=17864195335, address=山东济南, isLogin=0]
-----------------------------------
订单信息:
Orders [orderId=1111, userId=2, orderNum=21111, orderDate=1996-12-12, payment=y]
明细和商品:
DetailBean [item=Items [itemId=good001, itemName=iPad, price=10000.0], toString()=OrderDetail [detailId=1, orderNum=21111, itemId=good001, buyNum=1, orderId=1111]]
明细和商品:
DetailBean [item=Items [itemId=good002, itemName=iPhone, price=12000.0], toString()=OrderDetail [detailId=2, orderNum=21111, itemId=good002, buyNum=2, orderId=1111]]
-----------------------------------
订单信息:
Orders [orderId=2222, userId=2, orderNum=22222, orderDate=1996-12-13, payment=y]
明细和商品:
DetailBean [item=Items [itemId=good003, itemName=Huawei, price=5000.0], toString()=OrderDetail [detailId=3, orderNum=22222, itemId=good003, buyNum=3, orderId=2222]]
-----------------------------------

>resultType与resultMap总结

1、对于单表的查询基本上都用resultType实现即可。

2、对于一对一的联合查询,如果作为查询结果的第二张的表字段不多,定义一个扩展类,然后使用resultType实现即可。

3、如果一对一的联合查询,两个表的字段都大量的使用作为查询结果,那么在一个类中,组合另外一个类,使用resultMap进行映射实现。使用association将关联信息映射到一个对象中。

4、对于一对多,多对多的联合查询,如果查询结果数据特殊使用resultMap,使用collection将关联信息映射到一个集合中去,如果只是针对明细的数据,建议定义扩展类,使用resultType映射实现。

Mybatis高级应用 多表关联查询相关推荐

  1. MyBatis实现中间表关联查询

    MyBatis实现中间表关联查询 通常构建数据多对多模型的关系时,我们需要再建立一张中间表来关联另外两张表. 下面介绍一下,怎么用MyBatis来实现中间表关联查询并封装到实体类对象中. 现在有三张表 ...

  2. MyBatis多表关联查询

    本文将向大家介绍 MyBatis 中的多表关联查询 主要通过两个示例来说明在 MyBatis 中如何实现 一对多,多对一 和 多对多 查询 第一个示例:老师和学生关联 ​ 老师和学生是一对多的关系,一 ...

  3. asp多表查询并显示_SpringBoot系列(五):SpringBoot整合Mybatis实现多表关联查询

    本文我们将继续分享介绍Spring Boot在整合Mybatis开发企业级应用时其他典型的业务场景,即Mybatis是如何实现多表关联查询时将查询结果集与对象进行映射的,主要的内容包含"一对 ...

  4. jpa多表关联查询_Spring Boot 整合mybatis如何自定义 mapper 实现多表关联查询

    上一篇文章已经介绍了自定义 mapper 实现自定义的方法,其实实现了通过自定义的mapper就可以做多表关联等复杂查询.但是很多朋友还是反馈说没有实现多表关联查询,所以,今天把文章又重新修改了,增加 ...

  5. mybatis 多表关联查询_Java修行第041天--MyBatis框架(下)--多表查询

    1 解决列名和属性名不一致问题 如果查询时使用 resultType 属性, 表示采用 MyBatis 的Auto-Mapping(自动映射)机制, 即相同的列名和属性名会自动匹配. 因此, 当数据库 ...

  6. Mybatis的多表关联查询(多对多)

    Mybatis的多表关联查询(多对多) 项目目录结构 实现 Role 到 User 多对多 业务要求 用户与角色的关系模型 编写角色实体类 编写 Role 持久层接口 实现的 SQL 语句 编写映射文 ...

  7. (探讨)MyBatis中的N+1问题,多表关联查询效率高点还是多次单表查询效率高

    MySQL多表关联查询效率高点还是多次单表查询效率高,为什么? https://blog.csdn.net/weixin_33869377/article/details/86265527 MyBat ...

  8. MyBatis复习(五):获取多表关联查询结果

    Map保存查询结果 <select id="selectBlogMap" resultType="java.util.Map">select b.* ...

  9. mysql一次查询无关联多个表_面试官:为什么mysql不建议执行超过3表以上的多表关联查询?...

    点关注,不迷路:持续更新Java架构相关技术及资讯热文!!! 概述 前段时间在跟其他公司DBA交流时谈到了mysql跟PG之间在多表关联查询上的一些区别,相比之下mysql只有一种表连接类型:嵌套循环 ...

最新文章

  1. C语言 —— 把字符指针中的字符串,存入字符数组中
  2. 汇编中的length(返回利用dup定义的数组中的元素个数,即重复操作符dup前的count值)
  3. 【通知】有三AI运营组成员招收条件及管理暂行方案,你是否想好与有三AI共进退...
  4. 这就是你们有钱人炫富的新方式吗?
  5. java怎样返回json_java怎么返回json
  6. BigDecimal 加减乘除运算
  7. mybatis中修改了数据,控制台显示成功,数据库没有修改
  8. uml系统设计期末大作业_梳理一下计算机期末大作业
  9. JS 原生 锅打灰太狼小游戏
  10. SVN相关问题(svn:E175002错误)的解决方案
  11. python和java反射_python的反射和自省
  12. 苹果库乐队怎么玩_iPhone实用技巧:怎么将抖音上的背景音乐制作成手机铃声
  13. JVM-什么是GC?
  14. C语言学习 单精度、双精度各有几位小数?
  15. psql: FATAL: the database system is in recovery mode - 问题定位方法与解决
  16. 第6章---机器人系统仿真
  17. 软件测试面试题【变态逻辑题】,盘点那些大厂面试必出变态逻辑题
  18. 2022社群扫码进群活码完整系统源码+修复版的
  19. 前端如何实现一键截图功能?
  20. 魅族android不兼容Android,魅族17系列彻底跟上时代,搭载基于Android 10的Flyme 8.1系统...

热门文章

  1. 《Go语言程序设计》读书笔记(六) 基于共享变量的并发
  2. Redis应用场景汇总
  3. 在程序设计中使用Interface
  4. ubuntu16.04下安装codeblocks(2分钟安装)
  5. rocketMq 顺序消费
  6. python常用模块-time和datatime
  7. 由for V.S. for each想到的
  8. 弹框alertView
  9. oracle 11g(四)给oracle添加为系统服务(脚本)
  10. 用Win XP接收传真