MyBatis中<collection>实现一对多关联需配置property(如"orders")、ofType(如"com.example.Order")及映射来源(select或resultMap);嵌套查询用select+column传参,嵌套结果用resultMap+foreignKey或column/property显式关联。

MyBatis 中用 <collection> 实现一对多关联,核心是通过嵌套结果映射把子集合“挂”到主对象的 List 类型属性上,关键在于正确配置 property、ofType 和映射来源(select 或 resultMap)。
明确主从对象结构和属性命名
确保 Java 实体类中主对象(如 User)包含一个 List<Order> 类型的属性(比如叫 orders),且子对象(Order)有能与主表字段关联的外键字段(如 user_id)。属性名必须与 <collection> 的 property 值严格一致,区分大小写。
使用嵌套查询方式(推荐用于复杂逻辑或懒加载)
在主 <resultMap> 中定义 <collection>,通过 select 属性引用另一个 <select> 语句,该语句按主键查出子集合。需配合 column 传参(如 column="id"),让子查询知道当前主记录 ID。
-
property="orders":对应主对象的 List 属性名 -
ofType="com.example.Order":指定集合元素类型(全限定类名或别名) -
select="selectOrdersByUserId":引用外部的查询语句 ID -
column="id":把主结果的id列值作为参数传给子查询
使用嵌套结果方式(适合简单 JOIN 查询,性能更优)
主 SQL 使用 LEFT JOIN 查出主+子所有字段,列别名需避免冲突(如子表字段加前缀 order_id, order_status)。在 <collection> 内部用 <resultMap> 映射子对象,并通过 foreignKey(MyBatis 3.4.0+)或 column + property 显式指定关联关系。
立即学习“Java免费学习笔记(深入)”;
-
property="orders"和ofType同上 -
resultMap="OrderResultMap":指向子对象专用的<resultMap> - 若用
foreignKey="user_id",则 MyBatis 自动按该字段分组聚合;否则需在子 resultMap 中用<id>标出主键,并确保 JOIN 结果中主键可唯一标识子记录
注意点和常见坑
<collection> 默认是“立即加载”,如需懒加载,需开启 lazyLoadingEnabled=true,且子查询语句不能有 resultMap 中未定义的字段(否则可能触发 N+1)。另外,嵌套结果方式下,如果子记录为空,对应集合会是空 List 而非 null,但需确保主对象构造器/Setter 支持初始化(如用 Lombok 的 @Data 或显式初始化 private List<Order> orders = new ArrayList<>();)。


















