使用JOOQ multiset查询时的全字段传递及角色映射可行性问题
问题1:使用multiset查询时如何简洁选择表中所有字段
当表字段较多时,USER.asterisk()确实不够简洁,你可以直接用USER.fields()替代,它会返回表中所有字段的数组,直接传入select()方法即可,代码更简洁且维护性更好。
修改后的查询代码:
return dsl.select( USER.fields(), // 替换USER.asterisk() multiset( select(USER_ROLE.AUTHORITY_ID.as(ROLE.ID)) .from(USER_ROLE) .where(USER_ROLE.USER_ID.eq(USER.ID))) .as("roles") .convertFrom(f -> f.intoSet(roleMapper))) .from(USER) .where(field.eq(value));
如果后续需要排除个别字段,还可以通过流式过滤实现,比如:
Arrays.stream(USER.fields()) .filter(field -> !field.getName().equals("PASSWORD")) // 示例:排除密码字段 .toArray(Field[]::new)
问题2:在Record Mapper中设置multiset返回的
roles是否可行 完全可行,但你的写法可以优化,避免硬编码字符串和unchecked警告:
- 避免直接用字符串"roles"获取字段,建议用
DSL.name("roles")引用,更安全; - 借助类型转换器消除强制转换的警告:
优化后的映射代码:
@Override public User map(Record record) { final User user = new User(); user.setId(record.get(USER.ID)); user.setEmail(record.get(USER.EMAIL)); user.setPassword(record.get(USER.PASSWORD)); user.setFirstName(record.get(USER.FIRST_NAME)); user.setLastName(record.get(USER.LAST_NAME)); user.setActivated(record.get(USER.ACTIVATED)); user.setActivationKey(record.get(USER.ACTIVATION_KEY)); user.setImageUrl(record.get(USER.IMAGE_URL)); // 用DSL.name避免硬编码,借助转换器消除类型转换警告 final Set<Role> roles = Optional.ofNullable( record.get(DSL.name("roles"), new DefaultConverter<>(Object.class, Set.class)) ) .orElse(Collections.emptySet()); user.setRoles(roles); user.setResetKey(record.get(USER.RESET_KEY)); user.setResetDate(record.get(USER.RESET_DATE)); user.setLastModifiedBy(record.get(USER.LAST_MODIFIED_BY)); user.setLastModifiedDate(record.get(USER.LAST_MODIFIED_DATE)); user.setLangKey(record.get(USER.LANG_KEY)); return user; }
另外,如果你使用的是jOOQ 3.15及以上版本,还可以借助Record.into(Class)结合自定义转换器,自动映射嵌套集合,进一步简化代码,但当前写法完全可以正常工作。
内容的提问来源于stack exchange,提问作者Moments
相关产品推荐
相关产品推荐

