Conversation
There was a problem hiding this comment.
Pull request overview
该 PR 修复在 resultType 场景下(尤其是动态 SQL Source)无法应用实体映射(如基于 @Table/@Column/@Transient 的映射)的问题,使 SELECT 在仅有 type 且无显式 mappings 的情况下也能回填默认的实体 ResultMap,并补充相应测试用例。
Changes:
- 在
MapperHelper.processMappedStatement中,对 SELECT 的ResultMaps做补全:当ResultMap仅有type且mappings为空时,尝试用实体表的ResultMap替换。 - 新增/调整 rawresultmap 测试用例:补充动态 SQL + resultType / resultMap 场景,并重构部分断言逻辑。
- 修正测试 XML 中
age列映射字段名(与表结构/实体注解一致)。
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| core/src/main/java/tk/mybatis/mapper/mapperhelper/MapperHelper.java | 对 SELECT 的空 mappings ResultMap 进行实体 ResultMap 替换,覆盖动态 SQL Source 场景 |
| base/src/test/java/tk/mybatis/mapper/rawresultmap/UserMapper.xml | 增加动态 SQL 查询与动态 resultMap 查询用例;修正 age 列名 |
| base/src/test/java/tk/mybatis/mapper/rawresultmap/UserMapper.java | 增加对应的 Mapper 方法与注解场景用例 |
| base/src/test/java/tk/mybatis/mapper/rawresultmap/RawResultMapTest.java | 新增覆盖用例并重构断言方法 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| && ms.getSqlCommandType() == SqlCommandType.SELECT) { | ||
| if (ms.getResultMaps() != null && !ms.getResultMaps().isEmpty()) { | ||
| setRawSqlSourceMapper(ms); | ||
| // 如果没有resultMaps, 有则设置一个默认的resultMaps |
There was a problem hiding this comment.
注释“如果没有resultMaps, 有则设置一个默认的resultMaps”与实际逻辑不一致:当前代码是在 SELECT 时对已有 resultMaps 中“只有 type、没有 mappings”的条目做替换,并没有处理 resultMaps 为空的情况。建议更新注释,准确描述触发条件与行为,避免误导后续维护。
| // 如果没有resultMaps, 有则设置一个默认的resultMaps | |
| // 对于 SELECT 语句,如果已有 resultMaps 中存在仅指定 type 而未定义 mappings 的条目,则根据实体的 @Table 元数据生成并替换为默认的 ResultMap |
| private static void userAssert(List<User> users) { | ||
| users.forEach(u -> { | ||
| System.out.println(u); | ||
| Assert.assertNotNull(u.getUname()); | ||
| Assert.assertNotNull(u.getAge()); | ||
| Assert.assertNotNull(u.getCreateTime()); | ||
| }); |
There was a problem hiding this comment.
测试用的 userAssert() 现在只断言 uname/age/createTime 非空,移除了之前对 email 的断言,导致无法验证本次修复的核心行为(resultType/动态 SQL 下是否正确应用实体的 ResultMap,以及 @transient 字段是否应被映射)。建议针对不同查询分别断言 email 应为 null(resultType/自动映射走实体 ResultMap)或非 null(显式 BaseResultMap),以避免回归。
| List<ResultMap> modifiableResultMaps = new ArrayList<>(resultMaps); | ||
| for (int i = 0; i < resultMaps.size(); i++) { | ||
| List<ResultMapping> mappings = resultMaps.get(i).getResultMappings(); | ||
| // 只有type,没有mappings的情况下 | ||
| if (mappings == null || mappings.isEmpty()) { | ||
| EntityTable entityTable = EntityHelper.getEntityTableOrNull(resultMaps.get(i).getType()); | ||
| // 如果有@Table注解,则可以获取到entityTable | ||
| if (entityTable != null) { | ||
| ResultMap resultMap = entityTable.getResultMap(ms.getConfiguration()); | ||
| if (resultMap != null) { | ||
| modifiableResultMaps.set(i, resultMap); | ||
| MetaObject metaObject = MetaObjectUtil.forObject(ms); | ||
| metaObject.setValue("resultMaps", Collections.unmodifiableList(modifiableResultMaps)); | ||
| } |
There was a problem hiding this comment.
这里在循环内每次替换一个 ResultMap 都会重新构建 MetaObject 并多次 setValue("resultMaps")。建议用一个 changed 标记:先在循环里只更新 modifiableResultMaps,循环结束后(且仅当发生替换时)再一次性把新的不可变 List 回写到 ms,避免重复反射写入并让逻辑更清晰。
修复了typeResult情况下,动态sql无法映射的问题。
优化了之前未考虑的情况下自动映射不生效的问题。