查不出子集合主因是resultMap嵌套结构未配对或SQL未用JOIN返回子项字段;property名须与Java字段完全一致;SQL需显式列子表字段并用别名;JOIN分页易错乱,应先查主表ID再关联。

为什么 总是查不出子集合?
多数时候不是写法错,而是没配对 resultMap 的嵌套结构或忽略了 SQL 的 JOIN 方式。MyBatis 不会自动“拼装”一对多关系,它只按你写的映射规则把结果集字段塞进对象——如果 SQL 没返回子项字段,或者 的 property 和 Java 字段名不一致,集合就为空。
-
的property必须和父类中 List 类型字段名完全一致(区分大小写),比如private List就得写items; property="items" - SQL 里别用
SELECT *,必须显式列出所有子表字段,并用别名避免列名冲突,例如item.id as "items.id" - 若用
JOIN查一对多,结果集必然是笛卡尔积,MyBatis 靠id字段(通常是主键)做分组聚合,所以标签不能漏,且要覆盖父级和子级的唯一标识字段
嵌套结果映射(resultMap 套 resultMap)怎么写才不崩?
这是最常用也最容易翻车的方式:外层 resultMap 描述主对象,内层用 引用另一个 resultMap 描述子对象。关键在“引用路径”和“字段归属”。
- 子
resultMap的id必须唯一,且最好带命名空间前缀,比如com.example.OrderMapper.ItemResultMap,避免全局冲突 -
的ofType要写子对象的完整类名(或已定义的别名),比如ofType="OrderItem",不能写ofType="list"或留空 - 子
resultMap里的和字段名,要和 SQL 返回的列名(或别名)严格对应,MyBatis 不做驼峰转换——除非你开了mapUnderscoreToCamelCase=true
<resultmap id="OrderResultMap" type="Order"><id property="id" column="order_id"></id><result property="name" column="order_name"></result><collection property="items" oftype="OrderItem" resultmap="ItemResultMap"></collection></resultmap><p><resultmap id="ItemResultMap" type="OrderItem"><id property="id" column="item_id"></id><result property="sku" column="item_sku"></result></resultmap></p>
用 select 属性时为啥 N+1 查询没生效?
用 select 属性走“延迟加载 + 单条查询”路径,看似优雅,但默认不开启延迟加载,而且容易因缓存、事务或参数传递问题直接失效。
- 必须在 MyBatis 配置里打开
lazyLoadingEnabled=true,否则select形式退化为立即执行,还可能报NullPointerException -
的select值是另一个statement的 ID,比如select="selectItemsByOrderId",它对应的 SQL 必须接受一个参数(通常是父对象的 ID 字段),且参数名要和column指定的列名一致 - 如果父查询用了
resultType而非resultMap,的select会被忽略——MyBatis 只在resultMap下识别关联配置
MySQL 分页 + 一对多时 数据错乱怎么办?
用 LIMIT 直接套在 JOIN 查询上,会导致分页数不准、子项重复或丢失——因为分页发生在 JOIN 后的宽表上,不是按主表逻辑切片。
- 不要在含
的 SQL 里直接写LIMIT,先查主表 ID 列表(带分页),再用select属性批量查子项,或改用嵌套结果映射 +rowBounds(但仅限无 JOIN 场景) - 若坚持用 JOIN 分页,需用子查询先取主表分页结果,再和子表关联,例如:
SELECT * FROM order o JOIN (SELECT id FROM order ORDER BY id LIMIT 10) page ON o.id = page.id JOIN order_item i ON o.id = i.order_id - 注意驱动版本兼容性:MySQL 8.0+ 对派生表别名要求更严,
page这种别名必须存在,否则报Every derived table must have its own alias
嵌套映射真正难的不是语法,是理解 MyBatis 如何把扁平的结果集还原成树形结构——它靠的是字段名匹配、ID 分组、以及你有没有让每一条记录都携带足够的上下文信息。少一个 ,或多一个没处理的 NULL 字段,整个集合就塌了。










