【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~  


目录
打赏
0
0
0
0
6
分享
相关文章
对Spring、SpringMVC、MyBatis框架的介绍与解释
Spring 框架提供了全面的基础设施支持,Spring MVC 专注于 Web 层的开发,而 MyBatis 则是一个高效的持久层框架。这三个框架结合使用,可以显著提升 Java 企业级应用的开发效率和质量。通过理解它们的核心特性和使用方法,开发者可以更好地构建和维护复杂的应用程序。
139 29
Mybatis一对一,一对多关联查询
## MyBatis一对一、一对多关联查询详解 MyBatis是一款优秀的持久层框架,提供了灵活的SQL映射功能,支持复杂的数据库操作。本文将详细介绍MyBatis中一对一和一对多关联查询的实现。 ### 一对一关联查询 一对一关联关系指的是一个表中的一条记录与另一个表中的一条记录相关联。例如,一个用户有一个地址信息。 #### 数据库表设计 假设有两个表:`user`和 `address`。 ``` CREATE TABLE user ( id INT PRIMARY KEY, name VARCHAR(50) ); CREATE TABLE address
55 18
【潜意识Java】MyBatis中的动态SQL灵活、高效的数据库查询以及深度总结
本文详细介绍了MyBatis中的动态SQL功能,涵盖其背景、应用场景及实现方式。
160 6
Mybatis实现RBAC权限模型查询
通过对RBAC权限模型的理解和MyBatis的灵活使用,我们可以高效地实现复杂的权限管理功能,为应用程序的安全性和可维护性提供有力支持。
83 5
持久层框架MyBatisPlus
持久层框架MyBatisPlus
84 1
持久层框架MyBatisPlus
spring和Mybatis的各种查询
Spring 和 MyBatis 的结合使得数据访问层的开发变得更加简洁和高效。通过以上各种查询操作的详细讲解,我们可以看到 MyBatis 在处理简单查询、条件查询、分页查询、联合查询和动态 SQL 查询方面的强大功能。熟练掌握这些操作,可以极大提升开发效率和代码质量。
211 3
|
4月前
|
MyBatis-Plus条件构造器:构建安全、高效的数据库查询
MyBatis-Plus 提供了一套强大的条件构造器(Wrapper),用于构建复杂的数据库查询条件。Wrapper 类允许开发者以链式调用的方式构造查询条件,无需编写繁琐的 SQL 语句,从而提高开发效率并减少 SQL 注入的风险。
75 1
MyBatis-Plus条件构造器:构建安全、高效的数据库查询
mybatis如何仅仅查询某个表的几个字段
【10月更文挑战第19天】mybatis如何仅仅查询某个表的几个字段
179 1
|
5月前
|
Mybatis中一对一和一对多的处理
这篇文章讲解了在Mybatis中如何处理一对一和一对多的关系映射,包括使用association和collection标签的具体方法。
148 1
探索阿里巴巴新型ORM框架:超越MybatisPlus?
【10月更文挑战第9天】在Java开发领域,Mybatis及其增强工具MybatisPlus长期占据着ORM(对象关系映射)技术的主导地位。然而,随着技术的发展,阿里巴巴集团推出了一种新型ORM框架,旨在提供更高效、更简洁的开发体验。本文将对这一新型ORM框架进行探索,分析其特性,并与MybatisPlus进行比较。
186 0