<resultMap type="com.zzyl.nursing.vo.NursingProjectPlanVo" id="NursingProjectPlanVoResult"> <result property="id" column="id" /> <result property="planId" column="plan_id" /> <result property="projectId" column="project_id" /> <result property="executeTime" column="execute_time" /> <result property="executeCycle" column="execute_cycle" /> <result property="executeFrequency" column="execute_frequency" /> </resultMap> <select id="selectByPlanId" resultType="com.zzyl.nursing.vo.NursingProjectPlanVo"> <include refid="selectNursingProjectPlanVo"/> where plan_id = #{planId} </select> 为什么直接用<select id="selectByPlanId" resultType="com.zzyl.nursing.vo.NursingProjectPlanVo">查询结果没有映射到实体类 用<select id="selectByPlanId" resultMap="NursingProjectPlanVoResult">可以映射到实体类
时间: 2025-08-10 19:02:09 AIGC 浏览: 46
<think>问题分析:
在MyBatis中,`resultType`和`resultMap`都是用来指定查询结果如何映射到Java对象的,但两者有区别。
根据用户提供的代码片段:
- 有一个`resultMap`定义为`NursingProjectPlanVoResult`,它指定了如何将数据库列映射到实体类的属性。
- 第一个查询使用了`resultType="com.zzyl.nursing.vo.NursingProjectPlanVo"`,但没有映射成功。
- 第二个查询使用了`resultMap="NursingProjectPlanVoResult"`,可以成功映射。
原因分析:
1. `resultType`和`resultMap`不能同时使用,一次查询只能使用其中之一。
2. 当使用`resultType`时,MyBatis会自动进行列名到属性名的映射,默认规则是下划线转驼峰(如`plan_id`映射到`planId`)。但是,如果数据库列名和实体类属性名不完全匹配(或者需要特殊处理),则可能需要使用`resultMap`来明确指定映射关系。
3. 在用户提供的`resultMap`中,明确指定了列和属性的对应关系。例如,`column="plan_id"`映射到`property="planId"`。如果使用`resultType`,则要求列名和属性名必须满足自动映射规则,或者完全一致(如果未开启驼峰映射)。
为什么使用`resultType`没有映射成功?
- 可能的原因:
a. 没有开启驼峰命名自动映射(MyBatis默认不开启)。在MyBatis配置文件中,需要设置`mapUnderscoreToCamelCase`为`true`。
b. 查询返回的列名与实体类属性名不一致,且无法通过自动映射完成(例如,列名和属性名没有遵循下划线和驼峰的对应关系)。
c. 实体类中可能没有无参构造方法,或者有参构造方法覆盖了无参构造,导致创建对象失败(但这种情况通常会有其他错误)。
d. 查询返回的列中有一些在实体类中没有对应的属性,而MyBatis在自动映射时要求严格匹配(但默认情况下,MyBatis会自动忽略没有对应属性的列)。
解决方案:
1. 如果希望继续使用`resultType`,可以:
- 确保MyBatis配置中启用了驼峰命名转换:
```xml
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
```
- 或者,确保查询返回的列名与实体类属性名完全一致(可以通过SQL别名实现):
```xml
<select id="selectByPlanId" resultType="com.zzyl.nursing.vo.NursingProjectPlanVo">
select
id,
plan_id as planId,
project_id as projectId,
execute_time as executeTime,
execute_cycle as executeCycle,
execute_frequency as executeFrequency
from nursing_project_plan
where plan_id = #{planId}
</select>
```
2. 使用`resultMap`(如用户提供的第二个查询)是更推荐的方式,因为它提供了明确的映射关系,可读性和可维护性更好。用户已经定义了一个`resultMap`,所以直接使用它是正确的。
代码解释:
用户提供的第一个查询:
```xml
<select id="selectByPlanId" resultType="com.zzyl.nursing.vo.NursingProjectPlanVo">
<include refid="selectNursingProjectPlanVo"/>
where plan_id = #{planId}
</select>
```
这里使用了`resultType`,并且通过`include`引入了一个SQL片段(假设该片段包含了需要的列)。如果该SQL片段返回的列名与实体类属性名不一致(比如列名是下划线格式,而实体类是驼峰),且没有开启自动驼峰映射,那么映射就会失败。
第二个查询:
```xml
<select id="selectByPlanId" resultMap="NursingProjectPlanVoResult">
<include refid="selectNursingProjectPlanVo"/>
where plan_id = #{planId}
</select>
```
这里使用了`resultMap`,指向了之前定义的`NursingProjectPlanVoResult`。这样,MyBatis就会按照`resultMap`中指定的映射关系进行赋值,因此可以成功。
建议:
使用`resultMap`可以避免自动映射的不确定性,特别是当数据库列名和Java实体类属性名存在差异时。因此,推荐使用`resultMap`。
示例代码:
以下是一个完整的`resultMap`和查询的示例:
```xml
<!-- 定义resultMap -->
<resultMap id="NursingProjectPlanVoResult" type="com.zzyl.nursing.vo.NursingProjectPlanVo">
<id property="id" column="id"/>
<result property="planId" column="plan_id"/>
<result property="projectId" column="project_id"/>
<result property="executeTime" column="execute_time"/>
<result property="executeCycle" column="execute_cycle"/>
<result property="executeFrequency" column="execute_frequency"/>
</resultMap>
<!-- 定义SQL片段 -->
<sql id="selectNursingProjectPlanVo">
select id, plan_id, project_id, execute_time, execute_cycle, execute_frequency
from nursing_project_plan
</sql>
<!-- 使用resultMap进行查询 -->
<select id="selectByPlanId" resultMap="NursingProjectPlanVoResult">
<include refid="selectNursingProjectPlanVo"/>
where plan_id = #{planId}
</select>
```
相关问题:
根据问题,提出以下相关问题:</think>### 问题分析
在 MyBatis 中,`resultType` 和 `resultMap` 都是用于结果映射的配置,但它们的**工作方式不同**:
- **`resultType`**:依赖自动映射(Auto-Mapping),要求数据库列名与实体类属性名**严格匹配**(或开启驼峰转换)。
- **`resultMap`**:通过显式配置映射关系,可以处理列名和属性名不一致的情况。
### 原因解释
在您的代码中:
```xml
<select id="selectByPlanId" resultType="com.zzyl.nursing.vo.NursingProjectPlanVo"> <!-- 失败 -->
<select id="selectByPlanId" resultMap="NursingProjectPlanVoResult"> <!-- 成功 -->
```
失败的原因是:
1. **列名与属性名不匹配**
数据库列名如 `plan_id`(下划线格式),实体类属性名为 `planId`(驼峰格式),`resultType` 默认无法自动映射。
2. **未开启驼峰转换**
即使开启了驼峰转换(`mapUnderscoreToCamelCase=true`),如果存在特殊映射需求(如日期格式、自定义转换等),`resultType` 也无法处理。
3. **`resultMap` 显式配置了映射关系**
您在 `resultMap` 中明确指定了 `column="plan_id"` 映射到 `property="planId"`,因此能正确映射。
---
### 解决方案
#### 方法 1:使用 `resultMap`(推荐)
```xml
<!-- 显式定义映射关系 -->
<resultMap id="NursingProjectPlanVoResult" type="com.zzyl.nursing.vo.NursingProjectPlanVo">
<result property="id" column="id" />
<result property="planId" column="plan_id" /> <!-- 手动指定列名->属性名 -->
<result property="projectId" column="project_id" />
<result property="executeTime" column="execute_time" />
<result property="executeCycle" column="execute_cycle" />
<result property="executeFrequency" column="execute_frequency" />
</resultMap>
<!-- 查询时引用 resultMap -->
<select id="selectByPlanId" resultMap="NursingProjectPlanVoResult">
<include refid="selectNursingProjectPlanVo"/>
WHERE plan_id = #{planId}
</select>
```
#### 方法 2:启用全局驼峰映射(需修改 MyBatis 配置)
在 `mybatis-config.xml` 中添加:
```xml
<settings>
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
```
之后可直接用 `resultType`:
```xml
<select id="selectByPlanId" resultType="com.zzyl.nursing.vo.NursingProjectPlanVo">
<include refid="selectNursingProjectPlanVo"/>
WHERE plan_id = #{planId}
</select>
```
#### 方法 3:SQL 别名(临时方案)
在 SQL 中显式指定别名匹配属性名:
```xml
<sql id="selectNursingProjectPlanVo">
SELECT
id,
plan_id AS planId, <!-- 别名 = 实体类属性名 -->
project_id AS projectId,
execute_time AS executeTime,
execute_cycle AS executeCycle,
execute_frequency AS executeFrequency
FROM your_table
</sql>
```
---
### 关键区别总结
| 配置方式 | 原理 | 适用场景 |
|----------------|--------------------|----------------------------------|
| `resultType` | 自动映射 | 列名与属性名完全一致 |
| `resultMap` | 手动映射 | 列名与属性名不一致或需要复杂映射 |
---
### 最佳实践建议
1. **优先使用 `resultMap`**
尤其在企业级项目中,显式映射更清晰、可维护性更高。
2. **避免混用两种方式**
同一个项目中保持风格统一。
3. **复杂映射必须用 `resultMap`**
如嵌套对象(`<association>`)、集合(`<collection>`)、类型转换器等。
阅读全文
相关推荐
















