You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MyBatis Generator XML配置多表关联,能否生成关联类与方法?

当然可以!MyBatis 完全支持通过 XML 配置来实现这种多层关联的映射,还能帮你定义带关联逻辑的查询方法(不过实体类通常需要你先定义好,或者用 MyBatis Generator 生成基础实体后再补充关联字段)。下面一步步给你讲具体怎么配置:

第一步:定义关联实体类

首先得把三个表对应的实体类准备好,要包含关联关系的字段:

  • One 类:包含主键 id,以及一个 List<Two> 类型的 twos(一个 One 对应多个 Two)
  • Two 类:包含主键 id、field,以及 One 类型的 one(关联父表 One)、List<Three> 类型的 threes(关联符合条件的 Three)
  • Three 类:包含主键 id、field,以及 Two 类型的 two(关联父表 Two)

第二步:配置 XML 映射文件

你有两种常用的方式来实现这种关联查询:联合查询(一次性查三张表)或者嵌套查询(分步加载)。

方式一:联合查询(一次性关联三张表)

直接写一个联合 SQL,通过 LEFT JOIN 关联三张表,同时加上 TWO.FIELD = THREE.FIELD 的条件,然后用 resultMap 映射多层关联关系。

比如在 OneMapper.xml 中:

<!-- 定义结果映射,处理多层关联 -->
<resultMap id="OneWithTwoAndThreeResultMap" type="com.yourpackage.One">
  <!-- 映射 One 表字段 -->
  <id column="one_id" property="id" />
  
  <!-- 映射关联的 Two 集合 -->
  <collection property="twos" ofType="com.yourpackage.Two">
    <id column="two_id" property="id" />
    <result column="two_field" property="field" />
    
    <!-- 映射关联的 Three 集合,限定 TWO.FIELD = THREE.FIELD -->
    <collection property="threes" ofType="com.yourpackage.Three">
      <id column="three_id" property="id" />
      <result column="three_field" property="field" />
    </collection>
  </collection>
</resultMap>

<!-- 定义查询方法 -->
<select id="selectOneWithTwoAndThree" resultMap="OneWithTwoAndThreeResultMap">
  SELECT
    o.id AS one_id,
    t.id AS two_id,
    t.field AS two_field,
    th.id AS three_id,
    th.field AS three_field
  FROM ONE o
  LEFT JOIN TWO t ON o.id = t.id
  LEFT JOIN THREE th ON t.id = th.two_id AND t.field = th.field
  WHERE o.id = #{id}
</select>

方式二:嵌套查询(分步加载)

如果担心联合查询的数据量太大,可以用分步查询:先查 One 和 Two,再根据 Two 的 ID 和 Field 去查符合条件的 Three。

  1. 先在 ThreeMapper.xml 中定义查询符合条件的 Three 的方法:
<select id="selectThreesByTwoIdAndField" resultType="com.yourpackage.Three">
  SELECT id, field
  FROM THREE
  WHERE two_id = #{twoId}
    AND field = #{field}
</select>
  1. 然后在 OneMapper.xml 中配置关联映射:
<resultMap id="OneWithTwoAndThreeResultMap" type="com.yourpackage.One">
  <id column="one_id" property="id" />
  
  <collection property="twos" ofType="com.yourpackage.Two">
    <id column="two_id" property="id" />
    <result column="two_field" property="field" />
    
    <!-- 通过 select 属性调用 ThreeMapper 的方法,传递 Two 的 ID 和 Field -->
    <collection property="threes" ofType="com.yourpackage.Three"
                select="com.yourpackage.ThreeMapper.selectThreesByTwoIdAndField"
                column="{twoId=two_id, field=two_field}" />
  </collection>
</resultMap>

<select id="selectOneWithTwoAndThree" resultMap="OneWithTwoAndThreeResultMap">
  SELECT
    o.id AS one_id,
    t.id AS two_id,
    t.field AS two_field
  FROM ONE o
  LEFT JOIN TWO t ON o.id = t.id
  WHERE o.id = #{id}
</select>

第三步:添加 Mapper 接口方法

在对应的 Mapper 接口中添加查询方法,比如 OneMapper:

package com.yourpackage;

import org.apache.ibatis.annotations.Param;
import com.yourpackage.One;

public interface OneMapper {
    One selectOneWithTwoAndThree(@Param("id") Integer id);
}

一些注意点

  • 记得开启 MyBatis 的驼峰命名自动映射(在 MyBatis 全局配置中设置 mapUnderscoreToCamelCase=true),这样数据库的下划线字段可以自动映射到实体类的驼峰属性
  • 如果用嵌套查询,要注意 N+1 查询问题,可以通过 fetchType="eager" 设置立即加载,或者配置全局懒加载策略来优化
  • MyBatis Generator 可以帮你生成基础的实体类和 Mapper 代码,但关联逻辑需要你手动补充上面的 resultMap 和查询方法

内容的提问来源于stack exchange,提问作者michele

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:16:13