总结
在MyBatis中实现一对多关联查询可通过两种方式:1)在XML映射文件中使用`<collection>`标签,通过嵌套结果集(联表查询)或嵌套查询(分次查询)关联子表数据;2)使用注解方式通过`@Results`和`@Result`注解,结合`@Many`指定子查询方法。需在实体类中定义包含多个子对象的集合属性,并通过column参数传递关联字段。
详细解析
在 MyBatis 中实现一对多关联查询,主要通过 嵌套查询(分步查询) 和 嵌套结果(联表查询) 两种方式实现。以下是具体实现方法和示例:
一、嵌套查询(分步查询)
原理:先查询主实体,再根据主实体的关联字段查询子实体集合。
适用场景:子数据量较小或需要延迟加载的场景。
实现步骤:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
-
定义实体类
主实体类中需包含子实体的集合属性:1
2
3
4
5
6
public
class
User {
private
Long id;
private
String name;
private
List orders;
// 子实体集合
// getters/setters
}
-
编写 Mapper XML
• 主查询:查询主实体并触发子查询。• 子查询:根据主实体 ID 查询子实体列表。
-
调用查询方法
1
2
User user = sqlSession.selectOne(
"selectUserWithOrders"
,
1
);
List orders = user.getOrders();
// 自动触发子查询
优点:逻辑清晰,适合分步加载。
缺点:可能产生 N+1 查询问题(主查询 1 次 + 子查询 N 次)。
二、嵌套结果(联表查询)
原理:通过单次 SQL JOIN 查询获取所有数据,直接映射到主实体和子实体集合。
适用场景:需要一次性加载关联数据,避免多次查询。
实现步骤:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
-
定义实体类
与嵌套查询相同,主实体需包含子实体集合。 -
编写 Mapper XML
• 单次 JOIN 查询:关联主表和子表。• 结果映射:通过collection标签映射子实体集合。
-
调用查询方法
1
2
User user = sqlSession.selectOne(
"selectUserWithOrdersJoin"
,
1
);
List orders = user.getOrders();
// 直接获取关联数据
优点:减少数据库查询次数,性能更高。
缺点:SQL 复杂度较高,需手动处理字段别名。
三、注解方式实现(MyBatis 注解驱动)
原理:通过@Results和@Many注解配置关联关系。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
优点:代码简洁,适合注解驱动开发。
缺点:复杂关联时配置较繁琐。
四、对比总结
方式 | 嵌套查询 | 嵌套结果 | 注解方式 |
---|---|---|---|
查询次数 | 多次(1+N) | 单次 | 同嵌套查询 |
性能 | 较低(依赖子查询) | 较高 | 中等 |
适用场景 | 子数据量小、延迟加载 | 需一次性加载关联数据 | 简单关联逻辑 |
配置复杂度 | 中等 | 较高(需处理字段映射) | 低 |