我想使用ConstructorExpression将某些数据提取到DTO中。我没有明确创建整个查询,而是有一个自定义的Spring Data JPA存储库,该存储库带有一些谓词和一个Constructor表达式,例如:
querydsl.applyPagination(pageable, createQuery(predicate).select(factoryExpression));
我在使用Collection属性时遇到了麻烦。只需执行QMyType.myType.stringProperty
即可正常工作,但是当我有例如一组实体时,我只想获取其中一个属性的列表。示例:我有一个订单,其中包含一组订购商品。在我的DTO中,我只想订购包含商品名称列表的订单:
@Entity
public class Order {
@Id private Long id;
private String desc;
@OneToMany(mappedBy = "order") private Set<Item> items;
}
@Entity
public class Item {
@Id private Long id;
private String name;
@ManyToOne private Order order;
}
public class OrderDto {
private String desc;
private List<String> itemNames;
}
ConstructorExpression<OrderDto> dtoConstructor = Projections.constructor(OrderDto.class,
QOrder.desc,
Projections.list(QOrder.items.any().name));
对于最后一个元素,我已经尝试了几件事,但是我不知道如何告诉QueryDSL获取关联的子实体,提取属性并构建列表。我想这与这样做相似:
SELECT o.id, i.name
FROM order o
JOIN item i ON o.id = i.order_id
编辑: 背景是这样的:带有QueryDslPredicateExecutor的Spring数据存储库很容易通过REST获取过滤器并将其应用于动态查询。我想通过添加ConstructorExpression自动生成DTO来进一步走这一步。除非您想获取一个集合(值),否则就可以正常工作。我做了一些研究,这项工作几乎达到了预期的目的:
JPAQueryFactory queryFactory = new JPAQueryFactory(eM);
QOrder ord = QOrder.order;
QItem item = new QItem("item");
Map<Long, OrderDto> res = queryFactory
.from(ord)
.leftJoin(ord.items, item)
.transform(
groupBy(ord.id).as(
Projections.constructor(OrderDto.class,
ord.desc, list(item.name))));
我几乎说了,因为它是Map<Long, OrderDto>
而不是List<OrderDto>
(实际上,它应该是Page<OrderDto>
,但关键是分组依据的ID)。
此外,我不知道是否应该更改我的存储库以获取所有必要的查询组件(联接和transorm部分)。我想我必须通过整个查询,但是然后我仍然需要应用分页,创建计数查询等。
这里我想念什么吗?