-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
修复了动态sqlSource不能自动映射的问题。 #933
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 4.3.x
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
注释“如果没有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()); | ||
| }); |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
测试用的 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)); | ||
| } |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里在循环内每次替换一个 ResultMap 都会重新构建 MetaObject 并多次 setValue("resultMaps")。建议用一个 changed 标记:先在循环里只更新 modifiableResultMaps,循环结束后(且仅当发生替换时)再一次性把新的不可变 List 回写到 ms,避免重复反射写入并让逻辑更清晰。
修复了typeResult情况下,动态sql无法映射的问题。
优化了之前未考虑的情况下自动映射不生效的问题。