业务背景

根据客户id查询客户基本信息,以及客户存在的订单信息

两张数据表

  • 客户表

  • 订单表

实体类

  • 客户实体类:Customer
    private Integer id;
private String name;
private Integer age; //封装存在的订单信息
List<Order> orders = new ArrayList<>();
  • 订单实体类:Order
   private Integer id;
private String orderNumber;
private Double orderPrice;

CustomerMapper.java接口

    //根据客户id查询客户基本信息,以及客户存在的订单信息
Customer getCustomerById(Integer id);

CustomerMapper.xml映射文件

    <!--
//根据客户id查询客户基本信息,以及客户存在的订单信息
Customer getCustomerById(Integer id); Customer实体类:
private Integer id;
private String name;
private Integer age; List<Order> orders = new ArrayList<>(); Order实体类:
private Integer id;
private String orderNumber;
private Double orderPrice;
--> <!-- 查询结果的映射规则-->
<resultMap id="customerMap" type="customer">
<!-- 主键映射 -->
<id property="id" column="cid"/>
<!-- 非主键映射 -->
<result property="name" column="name"/>
<result property="age" column="age"/> <!-- 定义数据容器的映射规则 -->
<collection property="orders" ofType="order">
<!-- 容器中元素的映射规则 -->
<id property="id" column="oid"/>
<result property="orderNumber" column="orderNumber"/>
<result property="orderPrice" column="orderPrice" />
</collection>
</resultMap> <!-- 核心标签 -->
<select id="getCustomerById" parameterType="int" resultMap="customerMap">
select
c.id cid, name, age, o.id oid, orderNumber, orderPrice, customer_id
from
customers c
left join
orders o
on
c.id=o.customer_id
where
c.id=#{id}
</select>

测试

    //SqlSession对象
SqlSession sqlSession; //获取CustomerMapper的mybatis动态代理对象
CustomerMapper customerMapper; //获取SqlSession
@Before
public void getSqlSession() throws IOException {
//读取核心配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建SqlSessionFactory对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//获取SqlSession
sqlSession = factory.openSession();
//获取各Mapper接口的mybatis动态代理对象
customerMapper = sqlSession.getMapper(CustomerMapper.class);
} //归还SqlSession
@After
public void closeSession(){
sqlSession.close();
} //测试查询标签
@Test
public void testGetCustomerById(){
Customer customer = customerMapper.getCustomerById(1);
System.out.println(customer);
}

结果

==>  Preparing:

select
c.id cid, name, age, o.id oid, orderNumber, orderPrice, customer_id
from
customers c
left join
orders o
on
c.id=o.customer_id
where
c.id=? ==> Parameters: 1(Integer) <== Columns: cid, name, age, oid, orderNumber, orderPrice, customer_id
<== Row: 1, 荷包蛋, 22, 11, 20, 22.22, 1
<== Row: 1, 荷包蛋, 22, 12, 60, 16.66, 1
<== Total: 2 Customer{id=1,
name='荷包蛋',
age=22,
orders=[
Order{id=11, orderNumber='20', orderPrice=22.22},
Order{id=12, orderNumber='60', orderPrice=16.66}
]
}

结果分析

  • sql语句的查询结果
<==    Columns: cid, name, age, oid, orderNumber, orderPrice, customer_id
<== Row: 1, 荷包蛋, 22, 11, 20, 22.22, 1
<== Row: 1, 荷包蛋, 22, 12, 60, 16.66, 1
<== Total: 2
  • 实际注入到实体类中的数据
Customer{id=1,
name='荷包蛋',
age=22,
orders=[
Order{id=11, orderNumber='20', orderPrice=22.22},
Order{id=12, orderNumber='60', orderPrice=16.66}
]
}
  • mybatis框架对查询结果会自动去重,按照查询结果的映射规则,完成数据向实体类的注入操作

    • 将"1, 荷包蛋, 22 "分别注入到实体类Customer的前三个简单属性中,只注入一组
    • 将关联查询到的两条订单数据分别注入到Order实体类中的对应属性中
      • 并将Order对象封装到集合中
    • 最后将Customer的三个属性值和orders集合封装成一个Customer对象返回
    • 由于在数据映射标签中没有指明对customer_id的映射规则,所以在查询时会显示该字段数据,但是并没有被注入到实体类中

注意

在一对多关联查询时,注意根据实际业务需求选择合适的连接查询语句,在本例中选择:左外连接

如果选择内连接,当用户未下订单时,查询不到用户信息

  • 外连接查询结果:无订单信息,且用户信息可以正常显示
==>  Preparing: select c.id cid, name, age, o.id oid, orderNumber, orderPrice, customer_id from customers c left join orders o on c.id=o.customer_id where c.id=?
==> Parameters: 3(Integer) <== Columns: cid, name, age, oid, orderNumber, orderPrice, customer_id
<== Row: 3, 小张, 24, null, null, null, null
<== Total: 1 Customer{id=3, name='小张', age=24, orders=[]}
  • 内连接查询结果:无订单信息,则用户信息也无法正常显示
==>  Preparing: select c.id cid, name, age, o.id oid, orderNumber, orderPrice, customer_id from customers c join orders o on c.id=o.customer_id where c.id=?
==> Parameters: 3(Integer)
<== Total: 0
null

mybatis 13: 一对多关联查询的更多相关文章

  1. MyBatis:一对多关联查询

    MyBatis从入门到放弃四:一对多关联查询 前言 上篇学习了一对一关联查询,这篇我们学习一对多关联查询.一对多关联查询关键点则依然是配置resultMap,在resultMap中配置collecti ...

  2. mybatis collection 一对多关联查询,单边分页的问题总结!

    若想直接通过sql实现多级关联查询表结构得有2 个必不可少的字段:id ,parentId,levelId id:主键id, parentId:父id levelId:表示第几级(表本身关联查询的时候 ...

  3. MyBatis初级实战之六:一对多关联查询

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  4. 7.mybatis一对多关联查询

    和第5节一对一查询类似,但是不同的是,一对一使用的是association,而一对多使用collection. 实例: 1个班级Class,对应1个老师Teacher,对应多个学生Student 1. ...

  5. MyBatis从入门到放弃四:一对多关联查询

    前言 上篇学习了一对一关联查询,这篇我们学习一对多关联查询.一对多关联查询关键点则依然是配置resultMap,在resultMap中配置collection属性,别忽略了ofType属性. 搭建开发 ...

  6. MyBatis关联查询,一对多关联查询

    实体关系图,一个国家对应多个城市 一对多关联查询可用三种方式实现: 单步查询,利用collection标签为级联属性赋值: 分步查询: 利用association标签进行分步查询: 利用collect ...

  7. mybatis一对多关联查询+pagehelper->分页错误

    mybatis一对多关联查询+pagehelper->分页错误. 现象: 网上其他人遇到的类似问题:https://segmentfault.com/q/1010000009692585 解决: ...

  8. MyBatis多对一,一对多,多对多,一对多关联查询

    一.Person实体类 1 public class Person { 2 private Integer personId; 3 private String name; 4 private Int ...

  9. MyBatis:学习笔记(3)——关联查询

    MyBatis:学习笔记(3)--关联查询 关联查询 理解联结 SQL最强大的功能之一在于我们可以在数据查询的执行中可以使用联结,来将多个表中的数据作为整体进行筛选. 模拟一个简单的在线商品购物系统, ...

随机推荐

  1. 【ASP.NET Core】配置应用程序地址的N多种方法

    下面又到了老周误人子弟的时间,今天要误大伙的话题是:找找有多少种方法可以设置 ASP.NET Core 应用的地址,即 URL. 精彩马上开始! 1.UseUrls 方法 这是一个扩展方法,参数是可变 ...

  2. Eureka服务下线太慢,电话被告警打爆了

    某年某月的某一天,就像一张破碎的脸... 错了,重来. 某天,忽然发现大量的告警,经过多番调查研究考察(此处省略3000字),发现是由于 Eureka 服务下线太慢,而仍然有大量的请求打进来导致的报错 ...

  3. Win10 pycharm中显示PyTorch tensorboard图

    import numpy import numpy as np import torch import matplotlib.pyplot as plt import torch.nn as nn i ...

  4. Xmind演讲主题大纲

    参考:https://www.bilibili.com/video/BV1Rb411s7VG?p=9

  5. TL,你是如何管理项目风险的?

    沙包和打伞的故事 美国在1961年到1972年组织实施的一系列载人登月飞行任务.目的是实现载人登月飞行和人对月球的实地考察,为载人行星飞行和探测进行技术准备,它是世界航天史上具有划时代意义的一项成就. ...

  6. 物联网无线数传通信模块设备常见的几种Modbus网关

    物联网无线数传通信常见的几种Modbus网关 以下提到Modbus网关均指Modbus RTU转Modbus TCP,并不涉及对Modbus ASCII数据帧的处理,Modbus ASCII仅支持透明 ...

  7. 菜鸟学git的基本命令及常见错误

    Git init //在当前项目工程下履行这个号令相当于把当前项目git化,变身!\ git config --global user.name "xxx" # 配置用户名 git ...

  8. 数字化转型之数字资产知识库(springboot+es+vue+neo4j)

    前言 在数字化高度普及的时代,企事业机关单位在日常工作中会产生大量的文档,例如医院制度汇编,企业知识共享库等.针对这些文档性的东西,手工纸质化去管理是非常消耗工作量的,并且纸质化查阅难,易损耗,所以电 ...

  9. 关于kali安装输入法

    之前老是被kali大小写输入恶心坏了,正好看到一篇文章写kali安装搜狗输入法的,虽然不需要输入中文,但是英文输入就很方便了. 一.切换root用户登录 1.sodu su切换为root权限 2.pa ...

  10. SAP Container Controls(容器)

    BC_CONTROLS_TUTORIAL 效果 代码 REPORT bc_controls_tutorial. *------------------------------------------- ...