从DTO填充实体的最佳方法是什么

时间:2019-04-02 04:45:37

标签: spring rest spring-boot dto

我正在创建订购服务,这是RestServices世界的新功能。

我需要将订单模型读入OrderDTO并保存在数据库中。

为此,我有以下方法:

@PostMapping(produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<OrderDTO> createOrder(@Valid @RequestBody OrderDTO orderDTO) {
    Order order = new Order(orderDTO);
    Order createdOrder = orderService.createOrder(order);
    OrderDTO createdOrderDTO = new OrderDTO(order);
    ResponseEntity<OrderDTO> responseEntity = new ResponseEntity<OrderDTO>(createdOrderDTO, null, HttpStatus.CREATED);
    return responseEntity;
}

一切正常,但我对当前的设计有所担心:

  1. 我正在读取DTO的输入
  2. 要存储要转换为Order对象的对象,该对象将由Hibernate保留
  3. 再次将响应发送回去,我正在将实际的订单对象转换为DTO。

最后,如果我的应用程序收到100个请求,那么我将为每个请求创建4-5个对象。

我如何读取模型数据并有效保持?

3 个答案:

答案 0 :(得分:1)

我更喜欢像Mapstruct这样的Mapper:

OrderDtoMapper mapper = new OrderDTOMapper();

Order order = OrderDtoMapper.map(orderDto, Order.class);

并返回:

OrderDTO createdOrderDTO = OrderDtoMapper.map(order, OrderDTO.class);

对我来说,代码看起来更具可读性...而且您无需编写太多内容,因为Mapstruct会自动将其映射。因为看起来您会映射很多;) 映射器也许值得一试:http://mapstruct.org/

答案 1 :(得分:1)

通常,由于single responsibility principle而更喜欢DTO,每个对象都有自己的责任,而且将View / Controller与Model对象分开也很清楚

您有时可以减少OrderDTO,使用既是DTD又是真实对象的对象,

它将包含DTD属性,以及其他可以使用构建器添加的属性,例如,当根据请求创建对象时,我使用@JsonIgnoreProperties(ignoreUnknown = true)仅设置DTD属性,例如:

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(Include.NON_NULL)
public class Order 

您还可以使用JsonGetter/JsonProperty/JsonSetter控制期望/返回的结果

  

@JsonGetter和@JsonSetter是@JsonProperty的旧版本。

答案 2 :(得分:0)

我认为设计没有任何问题。

正如Nizet指出的。创建的对象是短暂的。

通常按照DTO和实体设计来保持UI和服务层分离。

通过这种方式,您可以选择过滤掉敏感信息,使其不像密码,密码那样被传递给世界。

但是,如果您愿意,可以直接在Controller类中使用Order实体。

我不建议这样做,但有可能。