Я ищу, чтобы использовать CQRS в проекте, над которым я работаю, однако сейчас я изо всех сил стараюсь реализовать запрос CQRS. Основываясь на моем немного ограниченном понимании, есть тонкий слой данных (иногда называемый тонким слоем чтения), который запрашивает базу данных и возвращает DTO с результатами запроса, которые используются уровнем пользовательского интерфейса приложения.Сопоставление между сущностью JPA и DTO в CQRS
Поскольку это приложение Java EE, которое я разрабатываю, слой тонких данных использует JPA для запроса базы данных с использованием EntityManager.createNamedQuery
, который возвращает объект, содержащий результаты, которые я затем сопоставляю с DTO.
Учитывая, что сторона запроса приложения должна быть «только для чтения», DTO содержит геттеры, но не устанавливает для каждого из свойств и конструктора, который используется для заполнения свойств при создании.
Для простого запроса я могу вручную сопоставить значения в объекте с DTO с помощью конструктора, однако это нецелесообразно для более сложных запросов, особенно если объект содержит отношения «один ко многим», которые необходимо быть сопоставлены с соответствующими DTO. Я рассмотрел использование фреймворков отображения, таких как Dozer и ModelMapper, однако все они полагаются на DTO с сеттерами и, похоже, не используют конструктор.
Следующий код представляет собой очень упрощенный вид двух объектов и двух DTO, которые я создал, чтобы помочь объяснить ситуацию.
@Entity
@Table(name = "ORDER")
public class Order {
// Various named queries
@Id
@Column(name = "ORDER_ID")
private UUID orderId;
@Column(name = "ORDER_NUMBER")
private long orderNumber;
@Column(name = "ORDER_DATE")
@Temporal(TemporalType.DATE)
private Date orderDate;
@Column(name = "CUSTOMER_NAME")
private String customerName;
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE }, orphanRemoval=true)
@JoinColumn(name = "ORDER_NUMBER", referencedColumnName = "ORDER_NUMBER")
private List<OrderLine> orderLines;
// Getters and setters, equals, hashCode, toString
}
@Entity
@Table(name = "ORDER_LINE")
public class OrderLine {
@Id
@Column(name = "ORDER_LINE_ID")
private UUID orderLineId;
@OneToOne(fetch=FetchType.EAGER)
@JoinColumn(name = "ORDER_ID", referencedColumnName = "ORDER_ID")
private Order order;
@Column(name = "PART_NUMBER")
private String partNumber;
@Column(name = "DESCRIPTION")
private String description;
@Column(name = "UNIT_PRICE")
private BigDecimal unitPrice;
@Column(name = "QUANTITY")
private int quantity;
// Getters and setters, equals, hashCode, toString
}
public class OrderDTO {
private long orderNumber;
private Date orderDate;
private String customerName;
private List<OrderLine> orderLines;
public OrderDTO() {}
public OrderDTO(long orderNumber, Date orderDate, String customerName, List<OrderLineDTO> orderLines) {
this.orderNumber = orderNumber;
this.orderDate = orderDate;
this.customerName = customerName;
this.orderLines = orderLines;
}
//Getters but no setters
}
public class OrderLineDTO {
private String partNumber;
private String description;
private BigDecimal unitPrice;
private int quantity;
public OrderLineDTO() {}
public OrderLineDTO(String partNumber, String description, BigDecimal unitPrice, int quantity) {
this.partNumber = partNumber;
this.description = description;
this.unitPrice = unitPrice;
this.quantity = quantity;
}
//Getters but no setters
}
Мои вопросы:
При использовании CQRS должны в DTOS только добытчиками и конструктор или это приемлемо иметь сеттеры, а?
Если DTOS в идеале должен только добытчики и конструктор, является основой отображения лучшим способом для заполнения DTOs где объект возвращаемых сложный результирующего набор, содержащий «один-ко-многим» отношения?
Есть ли какие-либо рамки отображения, которые могут использовать конструктор, а не , чем сеттеры?