联合查询时属性同名会导致MyBatis映射失败或值覆盖,必须为同名列显式指定唯一别名(如u.id AS uid),并配合resultMap精确绑定嵌套对象或使用驼峰配置+前缀别名,禁用SELECT *和resultType处理多表关联。

联合查询时属性同名(比如两张表都有 id、name 字段)会导致 MyBatis 自动映射失败或值被覆盖,关键在于让每个字段有唯一可识别的列名,并准确绑定到对应对象的属性上。
明确别名,避免列名冲突
在 SQL 中为同名列显式指定不同别名,是基础且最可控的做法。MyBatis 依赖列名做映射,列名重复就无法区分归属。
- 不要写
SELECT * FROM user u JOIN dept d ON u.dept_id = d.id—— 这会返回两个id、两个name,MyBatis 只取最后一个同名列的值 - 应写成:
SELECT u.id AS uid, u.name AS uname, d.id AS did, d.name AS dname, ... FROM user u JOIN dept d ON u.dept_id = d.id - 别名需与 Java 对象属性一致(如
uid → userId),或配合resultMap映射
用 resultMap 精确绑定嵌套对象
当结果要封装成含关联对象的结构(如 User 包含 Dept 属性),必须用 <resultMap> 描述层级关系,不能只靠别名。
- 主对象字段用
<result column="uid" property="id"/> - 关联对象字段用
<association property="dept" javaType="Dept">,并在其内部定义<id column="did" property="id"/>和<result column="dname" property="name"/> - 这样即使 SQL 返回
uid和did,MyBatis 也能分别赋值给User.id和User.dept.id
启用驼峰自动映射并配合别名使用
全局开启 mapUnderscoreToCamelCase=true 后,MyBatis 能把 user_name 自动转成 userName,但它不解决“同名列”问题——只解决命名风格差异。
立即学习“Java免费学习笔记(深入)”;
- 开启后仍需为联合查询中的同名列加前缀别名(如
u.create_time AS u_create_time),再靠驼峰规则映射到uCreateTime - 否则两个
create_time列仍会互相覆盖,驼峰也无从下手 - 该配置适合单表场景提速,多表联合时必须配合显式别名
避免用 resultType,改用 resultMap + type 定义嵌套结构
如果返回的是组合对象(如 UserWithDept),直接用 resultType="UserWithDept" 很容易因字段重名导致 setter 调用错乱。
- 推荐定义专用 VO 类(如
UserVO),包含userId、userName、deptId、deptName等扁平字段 - 或用
resultMap关联多个实体,让 MyBatis 按结构组装,而不是靠字段名硬匹配 -
resultType仅适用于字段名与属性名一一对应、无嵌套、无重名的简单场景


















