1

I have the following situation:

Class A extends B. Other classes, such as C, D, etc. also extend B In Class B, I would like to situate logic with regard to general information common to A, C, and D.

Hence, I would like to have a general query in B that retrieves all general info, but also be able to pass a Query to B so that the correct joins and conditions are fulfilled. Basically:

public B getB(String bUuid, Query extendedQuery) {

    SelectQuery bQuery = ... dsl.select(/* general B columns */)
                                .select(/* SELECT part from extended query */)
                                .from(/* general B tables */)
                                .from(/* FROM part from extended query */) // maybe join with some if else logic instead 
                                .where(/* general B conditions */)
                                .where(/* WHERE part of extended query */)

Is this possible using JOOQ? I would really not like to use plain SQL execution unless absolutely necessary.


EDIT:

Using the below answer, this is the final code I have that I am quite satisfied with:

public Record getB(String bUuid, Consumer<SelectQuery> extender)

Which I call as follows:

Record r = B.getB(uuid, query -> {
    query.addSelect(...);
    query.addJoin(...);
}

And in getB, after making our "general" SelectQuery query, we simply call:

extender.apply(query);

Afterwards we can simply do query.fetchOne() with our enhanced query.

filpa
  • 3,651
  • 8
  • 52
  • 91

1 Answers1

1

Think functional, not object oriented! This would be a much simpler approach:

public B getB(
    String bUuid,
    Supplier<? extends Collection<? extends Field<?>>> select,
    Supplier<? extends Collection<? extends Table<?>>> from,
    Supplier<? extends Collection<? extends Condition>> where
) {
    List<Field<?>> allSelect = new ArrayList<>();
    allSelect.addAll(/* general B columns */);
    allSelect.addAll(select.get());

    List<Table<?>> allFrom = new ArrayList<>();
    allFrom.addAll(/* general B tables */);
    allFrom.addAll(from.get());

    List<Table<?>> allWhere = new ArrayList<>();
    allWhere.addAll(/* general B conditions*/);
    allWhere.addAll(where.get());

    dsl.select(allSelect)
       .from(allFrom)
       .where(allWhere);
}

Now, you can call this higher-order function like so:

getB(
    uuid,
    () -> Arrays.asList(A.COL1, A.COL2, A.COL3),
    () -> Arrays.asList(A),
    () -> Arrays.asList(A.B_ID.eq(B.ID), A.COL4.like("%ABC%"))
);
Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
  • Thank you very much for the reply Mr. Eder! Using your suggestion as a basis, I went with the solution that I edited into my question above. I also highly appreciate you taking the time to answer questions here on SO. :) – filpa Jan 09 '17 at 17:14
  • @user991710: You're welcome! Oh, interesting approach, using the consumer. Note: You can also answer your own questions here on Stack Overflow. That will make it even a more interesting question for future visitors – Lukas Eder Jan 09 '17 at 17:28