如何通过MyBatis关联查询同时填充外部类与内部静态类的字段
解决MyBatis关联查询同时填充外部类与内部静态类字段的问题
你遇到的问题本质是MyBatis的resultType只能处理单一对象的字段映射,无法自动识别并填充嵌套的内部类对象。要同时填充外部类P和内部静态类Operation的字段,需要使用MyBatis的resultMap结合<association>标签来显式配置嵌套对象的映射关系,具体步骤如下:
1. 先更新实体类P
首先你的P类里缺少持有Operation对象的属性,MyBatis没有地方存储关联的Operation数据,所以需要先添加这个属性:
import lombok.Data; import java.sql.Timestamp; @Data public class P { private String name; private String operationId; // 添加该属性用于存储关联的Operation对象 private Operation operation; @Data public static class Operation { private Timestamp ts; private String id; } }
2. 定义resultMap映射关系
在你的MyBatis Mapper XML文件中,创建一个resultMap,分别映射外部类P的字段和内部类Operation的字段:
<resultMap id="PWithOperationResultMap" type="com.mappers.P"> <!-- 映射外部类P的字段 --> <result column="name" property="name"/> <result column="operationId" property="operationId"/> <!-- 关联内部静态类Operation,指定javaType为内部类的全限定名 --> <association property="operation" javaType="com.mappers.P.Operation"> <result column="ts" property="ts"/> <!-- 给o.id起别名避免字段混淆,也可直接用id,根据实际SQL调整 --> <result column="operation_id" property="id"/> </association> </resultMap>
3. 修改查询语句使用resultMap
修正你的SQL(注意原SQL存在重复FROM的语法错误),并将resultType替换为resultMap,指向上面定义的resultMap的id:
<select id="getAllP" resultMap="PWithOperationResultMap"> SELECT t."name" as name, t."operationId" as operationId, o."ts" as ts, o."id" as operation_id FROM "P" t JOIN "Operation" o ON t."operationId" = o."id" </select>
为什么原来的方式不行?
- 当设置
resultType="com.mappers.P"时,MyBatis只会把查询结果映射到P类的直接字段,不会自动识别并填充嵌套的Operation内部类; - 不存在
resultType="com.mappers.P & Operation"这种合法写法,MyBatis无法识别这种复合类型,所以只会尝试映射到最后一个类的字段。
通过resultMap的<association>标签,你可以明确告诉MyBatis如何将查询结果的列映射到嵌套对象的属性上,这是MyBatis处理关联对象或嵌套对象映射的标准方案。
内容的提问来源于stack exchange,提问作者Самир Шахмурадлы




