mybatis一对多关联查询核心是标签配置,支持嵌套select(需防n+1)和嵌套resultmap(推荐中等数据量),关键在于字段绑定、别名避免冲突、集合初始化及缓存优化。

一对多关联查询的核心配置方式
MyBatis 实现一对多(如“一个订单对应多个订单项”)主要靠
两种主流映射方式对比与选择
嵌套 Select 查询(N+1 问题需警惕)
在 Order 的 resultMap 中,为 items 字段配置 collection,select 指向另一个查询语句:
优点:逻辑清晰、SQL 职责分离;缺点:默认触发 N+1 查询——查 100 个订单,额外执行 100 次 item 查询。可通过 fetchType="lazy" 开启按需加载,或配合 @SelectProvider 动态控制。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
嵌套 ResultMap(推荐用于中等数据量)
用一条 JOIN SQL 查出所有数据,再通过
javaType="ArrayList">
注意:必须给 JOIN 字段起别名避免列名冲突(如 order.id → order_id,item.id → item_id),否则 MyBatis 无法区分主从字段。
避免常见坑的实操建议
- 开启 autoMappingBehavior=FULL 或 PARTIAL,但 collection 内部字段仍需显式定义,autoMap 不生效
- 使用
处理多态子类(如不同类型的订单项),避免硬编码 if-else - 大数据量场景下,禁用嵌套 resultMap 的 JOIN 方式,改用分页 + 批量 in 查询(如先查 orderIds,再用
WHERE order_id IN (#{ids})一次查完所有 items) - 实体类中集合属性务必初始化(如
private List<orderitem> items = new ArrayList();</orderitem>),否则空指针风险高
性能优化的关键点
真正影响性能的往往不是写法,而是数据规模与缓存策略:
- 对高频读、低频改的关联数据,开启 二级缓存 并设置
flushCache="false"防止误刷 - 用 @Options(useCache = true) 显式启用缓存,尤其搭配嵌套 Select 时更有效
- JOIN 查询时加 ORDER BY order_id, item_id,帮助 MyBatis 更高效分组(内部基于 LinkedHashMap 顺序聚合)
- 必要时用 RowBounds 或 分页插件 对子集合做截断(如只取前 5 条明细),避免传输冗余数据
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










