能否在JOOQ的SELECT字段阶段使用自定义RecordMapper?
解决方案
方法1:利用JOOQ 3.14+的重载方法
如果你的JOOQ版本在3.14及以上,RowN接口提供了直接接收Function<Record, T>的mapping重载,而RecordMapper本身就继承了这个函数式接口,直接引用map方法即可:
UserGroupMapper mapper = new UserGroupMapper(); var res = ctx.select( row( USER_GROUP.ID, USER_GROUP.NAME, USER_GROUP.DESCRIPTION, USER_GROUP.TAGS ).mapping(mapper::map), USER_GROUP.JSONLOAD ) .from(USER_GROUP) .fetch();
执行后就能得到你想要的Result<Record2<UserGroup, String>>,映射逻辑在SELECT阶段就会被应用。
方法2:适配低版本JOOQ(<3.14)
如果你的JOOQ版本较低,没有上述重载,需要手动将RecordMapper适配为对应字段数量的FunctionN。这里涉及4个字段,所以用Function4:
UserGroupMapper mapper = new UserGroupMapper(); var res = ctx.select( row(USER_GROUP.ID, USER_GROUP.NAME, USER_GROUP.DESCRIPTION, USER_GROUP.TAGS) .mapping((id, name, desc, tags) -> { // 创建包含指定字段的Record实例,传给自定义映射器 Record record = Records.newRecord(USER_GROUP.ID, USER_GROUP.NAME, USER_GROUP.DESCRIPTION, USER_GROUP.TAGS); record.values(id, name, desc, tags); return mapper.map(record); }), USER_GROUP.JSONLOAD ) .from(USER_GROUP) .fetch();
或者用更简洁的写法,利用表结构直接创建Record:
.mapping((id, name, desc, tags) -> mapper.map(Records.newRecord(USER_GROUP, id, name, desc, tags)))
这种方式会自动根据USER_GROUP表的字段顺序填充值,前提是你传入的参数顺序和表字段顺序一致。
额外建议
如果后续还有类似需求,也可以直接把映射逻辑封装成FunctionN类型(比如Function4<Integer, String, String, String, UserGroup>),这样能直接适配mapping方法,无需额外转换:
// 定义一个Function4 Function4<Integer, String, String, String, UserGroup> userGroupMapper = (id, name, desc, tags) -> new UserGroup(id, name, desc, javaParseTags(tags)); // 直接使用 var res = ctx.select( row(USER_GROUP.ID, USER_GROUP.NAME, USER_GROUP.DESCRIPTION, USER_GROUP.TAGS) .mapping(userGroupMapper), USER_GROUP.JSONLOAD ) .from(USER_GROUP) .fetch();
内容的提问来源于stack exchange,提问作者Theo
相关产品推荐
相关产品推荐

