【MyBatis框架点滴】——MyBatis一对多查询

简介:   上篇文章说了MyBatis中的一对一查询的两种方法,这里总结一下MyBatis中一对多和多对一的查询方法。  业务还用上篇文章中的订单业务来分析,表结构如下:

  上篇文章说了MyBatis中的一对一查询的两种方法,这里总结一下MyBatis中一对多和多对一的查询方法。

  业务还用上篇文章中的订单业务来分析,表结构如下:


9.png


 如上图订单和用户的关系,一个订单对应多个订单明细表,这里以订单为主查询表,在查询订单的同时,查询出每个订单所包含的订单明细集合,顺便把每个订单对应的用户也查询出来。(即在上篇文章的基础上,再查询出每个订单所包含的订单明细)


 由于每个订单可能有多个订单明细,所以这时需要用esultMap映射结果集。如果使用resultType会很麻烦,需要去重(比如文章末尾的图片中,sql查询出的是8条记录,但实际上这8条订单明细只属于4个订单实体,所以需要手动循环、判断、去重~)。


 具体用法如下:


 订单实体在上篇文章的基础上,添加订单明细的集合 orderDetails:


public class Orders {
  private Integer id;
  private Integer userId;
  private String number;
  private Date createtime;
  private String note;
  private User user;//订单对应用户
  private List<OrderDetail> orderDetails;//订单所包含的订单明细集合
  //getter、setter
}

  映射文件OrdersMapper.xml


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.danny.mybatis.mapper.OrdersMapper" >
  <resultMap type="com.danny.mybatis.po.Orders" id="OrdersUserOrderDetailResultMap">
    <!-- 配置映射的订单信息 -->  
    <!-- <id column="id" property="id"/>
    <result column="user_id" property="userId"/>
    <result column="number" property="number"/>
    <result column="createtime" property="createtime"/>
    <result column="note" property="note"/> -->
    <!-- 配置映射的用户信息 -->
    <association property="user" javaType="com.danny.mybatis.po.User">
      id:关联查询用户的唯一标识
         column:指定唯一标识用户信息的列
         property:映射到user的哪个属性
      <id column="user_id" property="id"/>
      <result column="username" property="username"/>
      <result column="sex" property="sex"/>
      <result column="address" property="address"/>
    </association>
    <!-- 订单明细信息-->
    <collection property="orderDetails" ofType="com.danny.mybatis.po.OrderDetail">
      <id column="orderdetail_id" property="id"/>
      <result column="items_id" property="itemsId"/>
      <result column="items_num" property="itemsNum"/>
      <result column="orders_id" property="ordersId"/>
    </collection>
  </resultMap>
  <select id="findOrdersUserOrderDetailResultMap" resultMap="OrdersUserOrderDetailResultMap" >
    select
      orders.*,
      user.username,
      user.sex,
      user.address,
      orderdetail.id orderdetail_id,
      orderdetail.items_id,
      orderdetail.items_num,
      orderdetail.orders_id
    from orders,user,orderdetail
    where orders.user_id=user.id
    and orders.id=orderdetail.orders_id
  </select>
</mapper>


 在上面resultMap配置中,共有三个部分,配置映射的订单信息、配置映射的用户信息和配置映射的订单明细信息。前两部分与上篇文章中的一致,这里不再多说。


 映射Ordes中的订单集合orderDetails要用<collection></collection>进行映射,它的作用是把关联查询到的多条记录映射到集合对象中,property表示将关联查询到的多条订单明细记录映射到Orders的哪个属性中,与<association></association> 中的javaType不同,这里指定orderDetails的类型要用ofType属性,它表示指定映射到集合属性中的pojo的类型。


 因为这个resultMap的配置大约有2/3的代码都与上篇文章中的resultMap一直,因此也可以跟java类似的,让这个resultMap继承已有的resultMap,如下:


<resultMap type="com.danny.mybatis.po.Orders" id="OrdersUserOrderDetailResultMap" extends="OrdersUserResultMap">
    <!-- 订单明细信息-->
    <collection property="orderDetails" ofType="com.danny.mybatis.po.OrderDetail">
      <id column="orderdetail_id" property="id"/>
      <result column="items_id" property="itemsId"/>
      <result column="items_num" property="itemsNum"/>
      <result column="orders_id" property="ordersId"/>
    </collection>
  </resultMap>


  mapper接口

public interface OrdersMapper{
  List<Orders> findOrdersUserOrderDetailResultMap() throws Exception;
}


  测试


@Test
public void findOrdersUserOrderDetailResultMap(){
  SqlSession sqlSession=sqlSessionFactory.openSession();
  OrdersMapper ordersMapper=sqlSession.getMapper(OrdersMapper.class);
  try {
    List<Orders> ordersList=ordersMapper.findOrdersUserOrderDetailResultMap();
    System.out.println("共查询到"+((ordersList!=null && list.size()>0)?ordersList.size():0)+"个订单");
  } catch (Exception e) {
    e.printStackTrace();
  }
  System.out.println();
}



  上述sql语句查询出的结果为:


10.png


  断点查看list中的数据如下:


11.png



 虽然sql语句查询出的结果为8条数据,但实际上只有4个订单(通过id字段可以看出来),MyBatis自动把id相同的记录合并成一个订单实体,并根据resultMap中的配置,把属于同一个订单的订单明细分别放到了对应订单的订单明细集合中。


 如果熟悉Hibernate的话,到了这里,您是不是也和小编觉得这跟Hibernate的配置也有些相似呢~~


 如果要问多对一查询的话,实际上你已经不知不觉地实现了~订单和用户啥关系?多个订单可以属于一个用户,所以上面的配置中<association></association> 也可以实现多对一查询,不信你在好好看看上面list中的内容,第一和第二个订单所属的用户其实是同一个人:DannyHoo~  


相关文章
|
3月前
|
Java 数据库连接 数据库
mybatis查询数据,返回的对象少了一个字段
mybatis查询数据,返回的对象少了一个字段
203 8
|
24天前
|
SQL Java 数据库连接
持久层框架MyBatisPlus
持久层框架MyBatisPlus
33 1
持久层框架MyBatisPlus
|
1月前
|
SQL 安全 Java
MyBatis-Plus条件构造器:构建安全、高效的数据库查询
MyBatis-Plus 提供了一套强大的条件构造器(Wrapper),用于构建复杂的数据库查询条件。Wrapper 类允许开发者以链式调用的方式构造查询条件,无需编写繁琐的 SQL 语句,从而提高开发效率并减少 SQL 注入的风险。
17 1
MyBatis-Plus条件构造器:构建安全、高效的数据库查询
|
2月前
|
SQL Java 数据库连接
mybatis如何仅仅查询某个表的几个字段
【10月更文挑战第19天】mybatis如何仅仅查询某个表的几个字段
49 1
|
3月前
|
SQL XML Java
mybatis复习04高级查询 一对多,多对一的映射处理,collection和association标签的使用
文章介绍了MyBatis中高级查询的一对多和多对一映射处理,包括创建数据库表、抽象对应的实体类、使用resultMap中的association和collection标签进行映射处理,以及如何实现级联查询和分步查询。此外,还补充了延迟加载的设置和用法。
mybatis复习04高级查询 一对多,多对一的映射处理,collection和association标签的使用
|
2月前
|
SQL XML Java
Mybatis中一对一和一对多的处理
这篇文章讲解了在Mybatis中如何处理一对一和一对多的关系映射,包括使用association和collection标签的具体方法。
27 1
|
2月前
|
缓存 Cloud Native 安全
探索阿里巴巴新型ORM框架:超越MybatisPlus?
【10月更文挑战第9天】在Java开发领域,Mybatis及其增强工具MybatisPlus长期占据着ORM(对象关系映射)技术的主导地位。然而,随着技术的发展,阿里巴巴集团推出了一种新型ORM框架,旨在提供更高效、更简洁的开发体验。本文将对这一新型ORM框架进行探索,分析其特性,并与MybatisPlus进行比较。
38 0
|
4月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
4月前
|
SQL Java 数据库连接
【Java 第十三篇章】MyBatis 框架介绍
MyBatis 原名 iBATIS,2001 年由 Clinton Begin 创建,以其简易灵活著称。2010 年更名以重塑品牌形象。MyBatis 通过 SQL 映射文件将 SQL 语句与 Java 代码分离,支持编写原生 SQL 并与方法映射。具备对象关系映射功能,简化数据库记录处理。支持动态 SQL 构建,灵活应对不同查询条件。内置缓存机制,提升查询效率。相比全功能 ORM,MyBatis 提供更高 SQL 控制度和更好的维护性,并易于与 Spring 等框架集成,广泛应用于 Java 数据访问层。
41 0
|
4月前
|
druid Java 数据库连接
SpringBoot项目整合MybatisPlus持久层框架+Druid数据库连接池,以及实现增删改查功能
SpringBoot项目整合MybatisPlus和Druid数据库连接池,实现基本的增删改查功能。
365 0