业务背景

根据客户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. Pandas:添加修改、高级过滤

    1.添加修改数据 Pandas 的数据修改是进行赋值,先把要修改的数据筛选出来,然后将同结构或者可解包的数据赋值给它: 修改数值 df.Q1 = [1, 3, 5, 7, 9] * 20 # 就会把值 ...

  2. Docker的网络

    概述 docker使用Linux桥接网卡,在宿主机虚拟一个docker容器网桥(docker0),docker启动一个容器时会根 据docker网桥的网段分配给容器一个IP地址,称为Container ...

  3. Cent OS8.0 及以上版本安装禅道教程

    Cent OS8系统下安装禅道需要搭建环境如下:httpd ,mariadb , php7.2 再运行禅道 一,环境说明: 运行环境推荐使用 Apache + PHP(7.0/7.1/7.2版本) + ...

  4. 看看CabloyJS工作流引擎是如何实现Activiti边界事件的

    CabloyJS内置工作流引擎的基本介绍 1. 由来 众所周知,NodeJS作为后端开发语言和运行环境,支持高并发.开发效率高,有口皆碑,但是大多用于数据CRUD管理.中间层聚合和中间层代理等工具场景 ...

  5. java编程用大小写字母及数字输出五位数验证码

    package day08; import java.util.Random;//导入util下的Random包 public class Yanzhengma { public static voi ...

  6. 七、服务器硬件及RAID配置实战

    一.RAID磁盘阵列介绍 磁盘阵列的全名(Redundant Arrays of Inexpensive Disk,RAID),中文简称是独立冗余磁盘阵列.冗余(如果磁盘出现故障,可以保证数据不丢) ...

  7. 【Parcel 2 + Vue 3】从0到1搭建一款极快,零配置的Vue3项目构建工具

    前言 一周时间,没见了,大家有没有想我啊!哈哈!我知道肯定会有的.言归正传,我们切入正题.上一篇文章中我主要介绍了使用Vite2+Vue3+Ts如何更快的入手项目.那么,今天我将会带领大家认识一个新的 ...

  8. SAP 定义用户组

    SUGR,可进行创建.查看.删除等维护性操作,并可指定本组的用户

  9. webpack中文api

    1.      简介 1.Plugins://插件 webpack has a rich plugin interface.Most of the features are internal plug ...

  10. 一个bug肝一周...忍不住提了issue

    导航 Socket.IO是什么 Socket.IO的应用场景 为什么选socket.io-client-java 实战案例 参考 本文首发于智客工坊-<socket.io客户端向webserve ...