Reputation: 25517
I am using jOOQ and I am not quite sure if I am using it the way I am supposed to. I was wondering if my code below can be written more elegantly. By "elegantly" I mean that it is quite annoying to change basically anything regarding the columns. If I add, remove or change the order of the columns I'd have to change all result and Table<>
objects etc. I am quite sure that I'll encounter such requests like below a few more times in the future thus I'd like to know if I can simplify this.
In addition, I noticed that the result of on.fetch()
and similar is a Result<Record6<..>>
. I took a look at those RecordX
classes. There are 22 of them. I don't think that I'll ever need that but what if I wanted to read 23 columns?
public List<StoreItemDTO> getItems(Long storeId) {
// Get all item_ids for the store
SelectConditionStep<Record1<Long>> where = this.ctx
.select(STORE_ITEM.ID)
.from(STORE_ITEM)
.where(STORE_ITEM.STORE_ID.eq(storeId));
// Get all store_item_details (all languages) according to the fetched item_ids
Table<Record5<Long, Long, String, String, Long>> storeItemDetails = this.ctx
.select(
STORE_ITEM_DETAILS.ID,
STORE_ITEM_DETAILS.STORE_ITEM_ID,
STORE_ITEM_DETAILS.NAME,
STORE_ITEM_DETAILS.DESCRIPTION,
STORE_ITEM_DETAILS.STORE_LANGUAGE_ID
)
.from(STORE_ITEM_DETAILS)
.where(STORE_ITEM_DETAILS.STORE_ITEM_ID.in(where))
.asTable("storeItemDetails");
// Join the result and get the items for the store in all languages
SelectOnConditionStep<Record6<Long, Long, Long, String, String, Long>> on = this.ctx
.select(
STORE_ITEM.ID,
STORE_ITEM.STORE_ID,
storeItemDetails.field(STORE_ITEM_DETAILS.ID),
storeItemDetails.field(STORE_ITEM_DETAILS.NAME),
storeItemDetails.field(STORE_ITEM_DETAILS.DESCRIPTION),
storeItemDetails.field(STORE_ITEM_DETAILS.STORE_LANGUAGE_ID)
)
.from(STORE_ITEM)
.join(storeItemDetails)
.on(storeItemDetails.field(STORE_ITEM_DETAILS.STORE_ITEM_ID).eq(STORE_ITEM.ID));
Result<Record6<Long, Long, Long, String, String, Long>> fetch = on.fetch();
// ..
return null;
}
Upvotes: 1
Views: 248
Reputation: 221265
If you don't need the type safety, don't use it. E.g. the following works just fine, too
// Get all item_ids for the store
SelectConditionStep<?> where = this.ctx...
// Get all store_item_details (all languages) according to the fetched item_ids
Table<?> storeItemDetails = this.ctx...
// Join the result and get the items for the store in all languages
SelectOnConditionStep<Record6<Long, Long, Long, String, String, Long>> on = this.ctx...
The extended type safety is very nice for the compiler when it can perform type inference, e.g. when you're writing:
UNION
sIN
predicatesYou're probably writing all these types down because you're using IDE auto-completion, and your IDE makes the most specific suggestion first. But using wildcards will work just as well, in the above case like this e.g.:
Result<?> fetch = this.ctx
// ..
.fetch();
for(Record record : fetch) {
String value = record.getValue(STORE_ITEM_DETAILS.NAME);
System.out.println(value);
}
I don't think that I'll ever need that but what if I wanted to read 23 columns?
Nothing significant changes. See also the manual: http://www.jooq.org/doc/latest/manual/sql-execution/fetching/record-n
You can still choose whether to use explicit record typing (no degree on the record):
Result<Record> result = query.fetch();
... or whether you use a wildcard:
Result<?> result = query.fetch();
Upvotes: 2