Home > Blockchain >  Can I use a custom recordmapper in JOOQ select field already?
Can I use a custom recordmapper in JOOQ select field already?

Time:09-08

Suppose I have a custom RecordMapper due to whatever reaons:

    public class UserGroupMapper implements RecordMapper<Record, UserGroup> {
        @Override
        public UserGroup map(Record rec) {
            UserGroup grp = new UserGroup(rec.getValue(USER_GROUP.ID),
                    rec.getValue(USER_GROUP.NAME),
                    rec.getValue(USER_GROUP.DESCRIPTION)
                    javaParseTags(USER_GROUP.TAGS)
            );
        }

In JOOQ, I could use it like so:

ctx.select()
                .from(USER_GROUP)
                .fetch(new UserGroupMapper());

However, if I want to select multiple things (like data from a left join), it would be convenient to not use the RecordMapper in the last step (fetch step) but already during the select step as I have seen as an example here with POJOs, not RecordMappers: ctx.select(row(A, B, C).mapping(MyPojo::new), otherFieldsLikeMultiSet)

My question: Is there something like this syntax available for normal RecordMappers as well? The mapping function expects a FunctionN<AllMyFields..., ?> and not something like Function<Record, ?> as the RecordMapper implements.

So some code somewhat like this:

UserGroupMapper mapper = new UserGroupMapper(); //Implements RecordMapper

var res = ctx.select(
      row(
         USER_GROUP.ID,
         USER_GROUP.NAME,
         USER_GROUP.DESCRIPTION,
         USER_GROUP.TAGS
      ).mapToMyPojo(mapper), // this function doesn't exist. How to utilize my mapper here? 
      USER_GROUP.JSONLOAD
   )
   .from(USER_GROUP)
   .fetch();

Now, I'd like to have a Result<Record2<UserGroup,String>>. So instead of using the recordmapper "in the end" at fetch phase, I'd like to apply the RecordMapper earlier. I know it's possible when providing a FunctionN to the row object mapping, but my RecordMapper sadly isn't a FunctionN :)

CodePudding user response:

The Row4.mapping(Function4) is just syntax sugar for ad-hoc conversion methods, like SelectField.convertFrom.

Now, Row4<T1, T2, T3, T4> extends SelectField<Record4<T1, T2, T3, T4>>, and thus you can pass any ? super Record4<T1, T2, T3, T4> type to the convertFrom(...) method. Your RecordMapper<Record, UserGroup> extends Function<Record, UserGroup>, so you can pass that directly:

With jOOQ 3.17

Field<UserGroup> field = row(...).convertFrom(new UserGroupMapper());

With jOOQ 3.16

The above SelectField::convertFrom method was pulled up from Field only in jOOQ 3.17, see #13118. Prior to that, you can turn your row() expression into a Field using DSL.field(SelectField):

Field<UserGroup> field = field(row(...)).convertFrom(new UserGroupMapper());
  • Related