jOOQ: best way to get aliased fields (from #as(ali

2019-08-12 23:53发布

问题:

I have to access the same table for multiple references from a "root" table. In order to do so, I'm creating aliases for these tables:

protected final Table<XyzRecord> foo = Tables.XYZ.as("foo", <foo-alias-function>);
protected final Table<XyzRecord> bar = Tables.XYZ.as("bar", <bar-alias-function>);

bar-alias-function would be declared as follows_

protected final Function<Field<?>, String> fooFieldAliasFunction = f -> "foo_" + f.getName();

Now since I'd like to benefit from type safe queries, I need to re-use the same alias-function in my queries to access the fields:

jooq.select()
  .from    (root)
  .leftJoin(foo).on(
         checklistTarget.field(fooFieldAliasFunction.apply(Tables.XYZ.ID), Tables.XYZ.ID.getType())
     .eq(root.FOO_ID)
   )
  .leftJoin(bar).on(
         checklistTarget.field(barFieldAliasFunction.apply(Tables.XYZ.ID), Tables.XYZ.ID.getType())
     .eq(root.BAR_ID)
   )
   ...
;

This seems awefully clumsy (a lot of code) and not terribly efficient (since the aliased field names are probably stored with the aliased table).

I assumed there would be a method on the alias that would give me the aliased field directly (e.g. foo.getField(Tables.XYZ.ID), but that doesn't seem to be the case.

Of course the problem is amplified if I want to select specific fields...

Am I missing something? What's the recommended way of doing this?

Thank you!

回答1:

I assumed there would be a method on the alias that would give me the aliased field directly (e.g. foo.getField(Tables.XYZ.ID), but that doesn't seem to be the case.

This kind of API would be useful indeed, although the existing Table.field(Field) method shouldn't be retrofitted to assume this behaviour. A new method might be introduced. On the other hand, you could write a simple utility:

<T, R extends Record> Field<T> field(Table<R> table, TableField<R, T> field) {
    if (table == foo)
        return foo.field(fooFieldAliasFunction.apply(field), field.getType());
    else if (table == bar)
        return foo.field(barFieldAliasFunction.apply(field), field.getType());
    else
        throw IllegalArgumentException();
}

And then call it like this:

jooq.select()
    .from    (root)
    .leftJoin(foo).on(field(foo, XYZ.ID).eq(root.FOO_ID))
    .leftJoin(bar).on(field(bar, XYZ.ID).eq(root.BAR_ID))
   ...
;