我有一个用例,我通过连接两个表ITEM
和ITEM_DESCRIPTION
来构建我的结果。从那里我拿了几个列,然后我想方便地转换成一个对象列表。在我的例子中,这些对象实际上是DTO对象,但当然它们也可以是业务对象。
这就是我现在这样做的方式:
public Map<Long, List<StoreItemDTO>> getItems(Long storeId) {
LOGGER.debug("getItems");
// Get all item_ids for the store
SelectHavingStep<Record1<Long>> where = this.ctx
.select(STORE_ITEM.ID)
.from(STORE_ITEM)
.where(STORE_ITEM.STORE_ID.eq(storeId))
// GROUP BY store_item.id
.groupBy(STORE_ITEM.ID);
// Get all store_item_details according to the fetched item_ids
TableLike<?> 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 use
Field<Long> itemIdField = STORE_ITEM.ID.as("item_id");
Result<?> fetch = this.ctx
.select(
STORE_ITEM.ID.as("item_id"),
itemIdField,
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))
.fetch();
Map<Long, ?> groups = fetch.intoGroups(STORE_ITEM.ID);
return null;
}
如您所见,结果应该是一个项目列表,其中每个项目都有不同语言的项目详细信息:
StoreItemDTO
- Long id
// Maps language-id to item details
- Map<Long, StoreItemDetails> itemDetails
StoreItemDetails
- Long id
- String name
- String description
我找不到会返回有用类型的intoGroups()
版本。我可以想象有Map<Long, List<Record>>
这样的东西,但我无法做到。
然而,有一个intoGroups(RecordMapper<? super R, K> keyMapper)
可以成为我正在寻找的东西。如果映射器也允许我实际将结果记录转换为自定义对象,如MyCustomPojo
,那么我可以非常方便地检索和转换数据。我不知道这是否有可能。类似的东西:
public static class MyCustomPojo {
public Long itemId;
// etc.
}
// ..
Map<Long, List<MyCustomPojo>> result = fetch.intoGroups(STORE_ITEM.ID, new RecordMapper<Record, List<MyCustomPojo>>() {
@Override
public List<MyCustomPojo> map(List<Record> record) {
// 'record' is grouped by STORE_ITEM.ID
// Now map each 'record' into every item of each group ..
return resultList;
}
});
但不幸的是编译器只允许
fetch.intoGroups(new RecordMapper<Record, Result<?>>() {
@Override
public Result<?> map(Record record) {
return null;
}
});
答案 0 :(得分:1)
经过对编译器的一些调整后,事实证明它可以完成。
我必须通过在匿名之外将我生成的地图声明为final
来“作弊”,而我实际上并非“使用”{ {1}}参数,因为我刚刚返回keyMapper
。
这就是我提出的:
null
由于我不确定这是否是最优雅的解决方案,我可以继续提出建议,并愿意接受任何可以优雅地缩短此代码的答案 - 如果可能的话。 :)