业务背景

根据客户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. 手把手教你使用 Spring Boot 3 开发上线一个前后端分离的生产级系统(一) - 介绍

    项目简介 novel 是一套基于时下最新 Java 技术栈 Spring Boot 3 + Vue 3 开发的前后端分离的学习型小说项目,配备详细的项目教程手把手教你从零开始开发上线一个生产级别的 J ...

  2. 「文化课 · 校园生活」街舞社演出 & 校园十佳歌手决赛

    女孩子跳舞很好看(流鼻血),男孩子跳舞很骚,跳的很有感觉.

  3. Unicode和中午互转

    import java.io.UnsupportedEncodingException; public class TestUnicode{ /* * 中文转unicode编码 */ public s ...

  4. 代码模板整理(0):先水一波a+b

    梦开始的地方 "Hello World!" #include<bits/stdc++.h> using namespace std; int main(){ cout& ...

  5. PostgreSQL Array 数组类型与 FreeSql 打出一套【组合拳】

    前言 PostgreSQL 是世界公认的功能最强大的开源数据库,除了基础数据类型 int4/int8/varchar/numeric/timestamp 等数据类型,还支持 int4[]/int8[] ...

  6. Ribbon的ServerStats引起内存泄露问题总结

    问题描述 服务运行一段时间之后,出现页面卡顿加载慢的问题,使用top命令查看了服务器的使用情况,发现CPU飙高,接着查看了该进程中每个线程的占用情况,发现导致CPU高的线程是JVM垃圾回收的线程,然后 ...

  7. BUUCTF-一叶障目

    一叶障目 010editor打开没发现有什么异常,看分辨率尺寸觉得不对劲,修改了一下发现了flag 图片第二组前面四个是宽后面是高,修改第七位为05即可发现flag flag{66666}

  8. HTML:<input type="text"> 输入数字时的验证!(在提交时验证)

    <!--非负数:<input type="text" name="" pattern="^\d+$">--> < ...

  9. 用Python爬取文章,并转PDF格式电子书

    wkhtmltopdf [软件],这个是必学准备好的,不然这个案例是实现不出来的 获取文章内容代码 (https://jq.qq.com/?_wv=1027&k=QgGWqAVF) 发送请求, ...

  10. # NC20860 兔子的区间密码

    NC20860 兔子的区间密码 题目 题目描述 有一只可爱的兔子被困在了密室了,密室里有两个数字,还有一行字: 只有解开密码,才能够出去. 可爱的兔子摸索了好久,发现密室里的两个数字是表示的是一个区间 ...