MyBatis 多表查询三种最常见的写法

 更新时间:2025年04月22日 10:21:02   作者:扶风_w  
这篇文章主要介绍了MyBatis 多表查询三种最常见的写法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

前言:一张关联表,让你头秃了吗?

你是不是也写过这种需求:

  • 查询某个用户及其角色列表
  • 查询订单及明细
  • 查询项目及其下属的多个阶段和负责人

最后写了一堆复杂 SQL + resultMap,运行一看,要么数据重复、要么数据丢失,最惨还可能触发 N+1 查询……

其实问题不是 MyBatis 不行,而是你用的方法不对。

🔍 三种最常见的写法 

✅ 方式一:联表查询 + 扁平映射(推荐)

这是我最常用也最稳定的一种方式:写一条联表 SQL,把需要的字段都查出来,返回扁平结构,再在 Java 层进行组装。

示例 SQL:

SELECT u.id AS userId, u.name AS userName,
       r.id AS roleId, r.name AS roleName
FROM user u
LEFT JOIN user_role ur ON u.id = ur.user_id
LEFT JOIN role r ON ur.role_id = r.id

特点:

  • 一条 SQL 查全所有数据;
  • 性能高,逻辑直观;
  • 可与分页插件(如 PageHelper)完美配合。

我的建议:

Java 层用 Map<Long, UserDTO> 分组封装,适合在 Service 层统一做聚合逻辑。

⚙️ 方式二:嵌套结果(resultMap + collection)

适合结构较为清晰的“树状结构”,比如订单和订单项、项目和子模块。

示例 XML: 

<resultMap id="userMap" type="User">
  <id property="id" column="user_id"/>
  <result property="name" column="user_name"/>
  <collection property="roles" ofType="Role">
    <id property="id" column="role_id"/>
    <result property="name" column="role_name"/>
  </collection>
</resultMap>

特点:

  • 多表映射层级清晰;
  • 比较适合中小型数据量。

踩坑经验:

  • 写错列名字段,就会导致内层集合全是 null;
  • 出现重复数据时,要手动去重或用 Set;
  • 不适合配合分页,容易导致“分页的是主表,但集合是全量”。

🧩 方式三:嵌套查询(nested select)

适合逻辑解耦,按模块维护的场景。

示例 XML:

<collection property="roles" ofType="Role" select="selectRolesByUserId" column="id"/>

特点:

  • 每条主表数据触发一次副查询;
  • 易维护但 极易 N+1
  • 不适合大批量数据查询。

实战建议:

除非你能保证每次最多查询 10 条主记录,否则慎用。性能瓶颈很容易出现在这里!

📉 你可能踩过的坑

问题症状原因建议
查询结果为 null子集合没数据字段名或别名不匹配显式写 column 属性或使用 @Results 映射
一对多重复数据主表字段重复出现联表未分组 / Java 封装没处理手动分组聚合,避免直接用 List
分页异常只分页主表,子表数据混乱不支持嵌套分页联表 + 扁平查询是最佳方案
查询慢到爆炸N+1 查询每条主记录触发一次 select转成 join 联查或改为批量查

✅ 实战建议:如何选择这三种方式? 

类型性能可维护性适合场景
联表扁平查询⭐⭐⭐⭐⭐⭐⭐大批量、一对多、分页场景
嵌套结果 resultMap⭐⭐⭐⭐⭐⭐⭐结构清晰、数据量适中
子查询 nested⭐⭐⭐⭐⭐⭐⭐小数据量、逻辑独立场景

📦 我的最佳实践模板(真实项目用的)

  • DAO 层只查数据,不做结构组装
  • Service 层按业务模型拼装 DTO
  • 多表结果不要直接给前端,统一封装响应结构;
  • DTO + Builder 模式 + Map 分组,灵活好用;

📌 总结一句话:

多表查询选对方式,写代码少掉一半 bug。

不必纠结哪种方式最“完美”,关键是是否适合你当前场景
记住:能用联查查全的,就别搞子查询;分页场景尽量别用嵌套结构;小数据就图方便,结构优先。

到此这篇关于MyBatis 多表查询的文章就介绍到这了,更多相关MyBatis 多表查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Maven编译报错:未与 -source 8 一起设置引导类路径的完美解决方案

    Maven编译报错:未与 -source 8 一起设置引导类路径的完美解决方案

    这篇文章主要为大家详细介绍了Maven编译报错:未与 -source 8 一起设置引导类路径的相关解决方案,文中的示例代码讲解详细,有需要的小伙伴可以了解下
    2025-10-10
  • 如何使用Spring boot的@Transactional进行事务管理

    如何使用Spring boot的@Transactional进行事务管理

    这篇文章介绍了SpringBoot中使用@Transactional注解进行声明式事务管理的详细信息,包括基本用法、核心配置参数、关键注意事项、调试技巧、最佳实践以及完整示例,感兴趣的朋友一起看看吧
    2025-02-02
  • 详解在Java的Struts2框架中配置Action的方法

    详解在Java的Struts2框架中配置Action的方法

    这篇文章主要介绍了详解在Java的Struts2框架中配置Action的方法,讲解了包括struts.xml中的action配置及基于注解方式Action配置的两个方式,需要的朋友可以参考下
    2016-03-03
  • mybatis中的异常BindingException详解

    mybatis中的异常BindingException详解

    这篇文章主要介绍了mybatis中的异常BindingException详解,此异常是mybatis中抛出的,意思是使用的这个方法找到,但是因为mapperScan()已经扫描到了Mapper类了,在绑定Mapper.xml时没有绑定到导致的,需要的朋友可以参考下
    2024-01-01
  • Java字符串替换方法详细讲解

    Java字符串替换方法详细讲解

    在Java编程中,处理字符串公式运算是一项常见的任务,特别是在需要动态计算或自定义逻辑的场景,这篇文章主要介绍了Java字符串替换方法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-09-09
  • MyBatis typeAliases元素标签(含注解方式)及其属性、设置方式

    MyBatis typeAliases元素标签(含注解方式)及其属性、设置方式

    这篇文章主要介绍了MyBatis typeAliases元素标签(含注解方式)及其属性、设置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • 解析Springboot集成Tile38客户端之Set命令实现示例

    解析Springboot集成Tile38客户端之Set命令实现示例

    这篇文章主要为大家介绍了解析Springboot集成Tile38客户端之Set命令实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • JDK集合源码之解析TreeMap(二)

    JDK集合源码之解析TreeMap(二)

    下面小编就为大家带来一篇浅谈java中的TreeMap 排序与TreeSet 排序。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-07-07
  • eclipse+maven+spring mvc项目基本搭建过程

    eclipse+maven+spring mvc项目基本搭建过程

    这篇文章主要介绍了eclipse+maven+spring mvc项目基本搭建过程,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • SpringBoot用ServiceLocatorFactoryBean优雅切换支付渠道

    SpringBoot用ServiceLocatorFactoryBean优雅切换支付渠道

    本文主要介绍了SpringBoot用ServiceLocatorFactoryBean优雅切换支付渠道,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-10-10

最新评论