Skip to content

[功能改进]: selectJoinList 等查询方法支持 Java Record 类作为结果类型 #351

@hanhan721

Description

@hanhan721

确认

  • 我的版本是最新版本, 我的版本号与 version 相同, 并且项目里无依赖冲突
  • 我已经在 issue 中搜索过, 确认问题没有被提出过
  • 我已经修改标题, 将标题中的 描述 替换为遇到的问题

功能改进

当前程序版本

1.5.5(MyBatis-Plus 3.5.15,Java 25)

功能描述

希望 selectJoinList / selectJoinPage 等查询方法能支持 Java Record 类作为 resultType。

目前使用 Record 接收联表查询结果会报错,改为带 setter 的普通类就正常。

复现代码

// Record 定义
public record UserRoleRecord(Long id, String username, String nickname, Long roleId) {}

// 查询
var wrapper = new MPJLambdaWrapper()
.select(SysUser::getId, SysUser::getUsername, SysUser::getNickname)
.select(SysUserRole::getRoleId)
.leftJoin(SysUserRole.class, SysUserRole::getUserId, SysUser::getId)
.last("limit 5");
// 报错
List list = userMapper.selectJoinList(UserRoleRecord.class, wrapper);

改为普通类则正常:

@DaTa
public static class UserRoleClass {
private Long id;
private String username;
private String nickname;
private Long roleId;
}
// 正常
List list = userMapper.selectJoinList(UserRoleClass.class, wrapper);

原因分析

MPJInterceptor.buildResultMap() 构建 ResultMapping 时,始终使用 property 映射(依赖 setter
赋值),没有判断目标类是否为 Record。

Record 是不可变类型,没有 setter,需要通过构造函数映射(ResultFlag.CONSTRUCTOR)来创建对象。MyBatis 本身从 3.5.10+
已支持 Record 的 constructor 映射,但 MPJ 动态构建 ResultMap 时未兼容。

建议在 buildResultMap() 中增加类似逻辑:

if (resultType.isRecord()) {
for (RecordComponent rc : resultType.getRecordComponents()) {
resultMappings.add(new ResultMapping.Builder(...)
.flags(Collections.singletonList(ResultFlag.CONSTRUCTOR))
.build());
}
}

报错日志

org.apache.ibatis.reflection.ReflectionException: Could not set property 'id' of
'class com.romeo.boot.controller.MpjRecordTestController$UserRoleRecord' with value '1'
Cause: There is no setter for property named 'id' in
'class com.romeo.boot.controller.MpjRecordTestController$UserRoleRecord'

SQL: SELECT t.id, t.username, t.nickname, t1.role_id
FROM sys_user t LEFT JOIN sys_user_role t1 ON (t1.user_id = t.id)
WHERE t.deleted=0 limit 5

参考资料

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions