mybatis 关联查询 resultMap 同名冲突

本文介绍在MyBatis中解决一对一双表关联时,因属性名冲突导致的数据覆盖问题。通过为相同的字段设置别名,并在resultMap中指定对应的列名,实现正确映射。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在学mybatis写mapper映射文件时,在写到一对一关联时,由于两个javabean的属性相同,导致在select时外部属性覆盖了内部属性:

	<resultMap type="Classes" id="classesMap">
		<id property="id" column="id" javaType="int"/>
		<result property="name" column="name" javaType="String"/>
		<association property="teacher" javaType="Teacher" >
			<id property="id" column="id" javaType="int"/>
			<result property="name" column="name" javaType="String"/>
			<result property="age" column="age" javaType="int"/>
		</association>	
	</resultMap>

	<sql id="selectAllClassesSql">
		SELECT c.id,c.name,teacher_id,t.id,t.name ,t.age 
		FROM classes c,teacher t
	</sql>

这样子由于Classes中有name/id属性,teacher也有name/id属性,通过select语句查询时,Classes的name/id属性会覆盖teacher的name/id属性。


解决方法,在sql语句中给相同的属性起别名:t.id as t_id,同时设置 resultMap 中 teacher的id column为t_id:

	<resultMap type="Classes" id="classesMap">
		<id property="id" column="id" javaType="int"/>
		<result property="name" column="name" javaType="String"/>
		<association property="teacher" javaType="Teacher" >
			<id property="id" column="t_id" javaType="int"/>
			<result property="name" column="t_name" javaType="String"/>
			<result property="age" column="t_age" javaType="int"/>
		</association>	
	</resultMap>
	
	<sql id="selectAllClassesSql">
		SELECT c.id,c.name,teacher_id,t.id as t_id,t.name as t_name,t.age as t_age 
		FROM classes c,teacher t
	</sql>


### MyBatis 中通过 `resultMap` 实现字段与类属性映射 以下是基于 `com.po.Student` 类的 `resultMap` 配置示例,其中 `sid`, `sname`, `sage` 对应数据库中的字段名称,而 `id`, `name`, `age` 则对应 Java 类中的属性名称。 #### 定义 Student 类 ```java package com.po; public class Student { private Integer id; private String name; private Integer age; public Student(Integer id, String name, Integer age) { this.id = id; this.name = name; this.age = age; } // Getters and Setters } ``` #### XML 映射文件配置 (`resultMap`) ```xml <resultMap type="com.po.Student" id="studentResultMap"> <!-- 数据库字段名 -> Java 属性名 --> <id property="id" column="sid"/> <!-- 主键映射 --> <result property="name" column="sname"/> <result property="age" column="sage"/> </resultMap> <select id="selectStudents" resultMap="studentResultMap"> SELECT sid, sname, sage FROM students </select> ``` 以上代码片段展示了如何使用 `resultMap` 将数据库字段 `sid`, `sname`, 和 `sage` 映射到 `Student` 类的属性 `id`, `name`, 和 `age` 上[^1]。 - `<id>` 标签表示主键映射。 - `<result>` 标签用于其他字段的一般映射。 如果需要支持自动生成主键并回填至对象中,则可以参考以下方法: #### 自动生成主键并回填 可以通过设置 `useGeneratedKeys=true` 来启用 JDBC 的主键回填功能: ```xml <insert id="insertStudent" useGeneratedKeys="true" keyProperty="id"> INSERT INTO students(sname, sage) VALUES(#{name}, #{age}) </insert> ``` 此方式适用于 MySQL 或其他支持 `AUTO_INCREMENT` 的数据库引擎[^3]。 另一种方式是手动获取最后插入的主键值: ```xml <insert id="insertStudent"> <selectKey keyProperty="id" resultType="int" order="BEFORE"> SELECT LAST_INSERT_ID() </selectKey> INSERT INTO students(sid, sname, sage) VALUES(#{id}, #{name}, #{age}) </insert> ``` #### 使用 SQL 片段简化重复查询逻辑 为了减少冗余代码,可利用 `<sql>` 标签定义公共部分,并通过 `<include>` 引入: ```xml <sql id="studentColumns">sid, sname, sage</sql> <select id="selectAllStudents" resultMap="studentResultMap"> SELECT <include refid="studentColumns"/> FROM students </select> ``` 这种方式能够有效提升代码复用性和维护效率[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值