Я хочу использовать выражение ConstructorExpression для извлечения некоторых данных в DTO.Я не создаю явно весь запрос, вместо этого у меня есть собственный репозиторий Spring Data JPA, который принимает некоторый предикат и выражение конструктора, например так:
querydsl.applyPagination(pageable, createQuery(predicate).select(factoryExpression));
У меня проблемы со свойствами коллекции.Простое выполнение 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 fetchсвязанные дочерние объекты, извлеките свойство и создайте список.Я думаю, это было бы похоже на:
SELECT o.id, i.name
FROM order o
JOIN item i ON o.id = i.order_id
РЕДАКТИРОВАТЬ: Фон таков: хранилище данных Spring с QueryDslPredicateExecutor удобно получать фильтры через 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>
, ноточка - это идентификатор группы по.)
Более того, я не знаю, должен ли я изменить свой репозиторий, чтобы он брал все необходимые компоненты запроса (части соединения и преобразования).Полагаю, мне нужно было бы пройти весь запрос, но тогда мне все равно нужно применить нумерацию страниц, создать запрос подсчета и т. Д.
Есть ли что-то, что я здесь упускаю?