从 DTO 填充实体的最佳方法是什么
What is the best way to populate Entity from 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;
}
一切正常,但我对当前的设计有疑虑:
- 我正在读取 DTO 的输入
- 存储我正在转换为 Order 对象的对象,该对象将由 Hibernate 持久化
- 再次发回响应,我将实际订单对象转换为 DTO。
最后,我将为每个请求创建 4-5 个对象,如果我的应用程序收到 100 个请求,它可能 运行 进入内存问题。
如何读取模型数据并有效地持久化?
我没有发现设计有任何问题。
正如尼采指出的那样。创建的对象是短暂的。
通常遵循 DTO 和实体设计以保持 UI 和服务层分离。
通过这种方式,您可以选择过滤掉传递给世界的敏感信息,例如密码、个人识别码。
但如果您愿意,可以直接在 Controller class 中使用 Order
实体。
我不建议这样做,但这是可能的。
我更喜欢像 Mapstruct 这样的 Mapper:
OrderDtoMapper mapper = new OrderDTOMapper();
Order order = OrderDtoMapper.map(orderDto, Order.class);
返回:
OrderDTO createdOrderDTO = OrderDtoMapper.map(order, OrderDTO.class);
对我而言,代码看起来更具可读性……而且您无需编写太多内容,因为 Mapstruct 会自动映射它。因为看起来你会映射很多 ;)
也许映射器值得一试:http://mapstruct.org/
总的来说,更喜欢DTO,因为single responsibility principle
,每个对象都有自己的责任,而且View/Controller和模型对象分开也更清楚
您有时可以减少 OrderDTO
,使用既是 DTD 又是真实对象的对象,
它将包括 DTD 属性以及您可以使用构建器添加的其他属性,例如,当根据请求创建对象时,我使用 @JsonIgnoreProperties(ignoreUnknown = true)
仅设置 DTD 属性,例如:
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(Include.NON_NULL)
public class Order
你也可以用JsonGetter/JsonProperty/JsonSetter来控制什么expected/returned
@JsonGetter and @JsonSetter are old alternatives to @JsonProperty.
我正在创建订单服务,这是 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;
}
一切正常,但我对当前的设计有疑虑:
- 我正在读取 DTO 的输入
- 存储我正在转换为 Order 对象的对象,该对象将由 Hibernate 持久化
- 再次发回响应,我将实际订单对象转换为 DTO。
最后,我将为每个请求创建 4-5 个对象,如果我的应用程序收到 100 个请求,它可能 运行 进入内存问题。
如何读取模型数据并有效地持久化?
我没有发现设计有任何问题。
正如尼采指出的那样。创建的对象是短暂的。
通常遵循 DTO 和实体设计以保持 UI 和服务层分离。
通过这种方式,您可以选择过滤掉传递给世界的敏感信息,例如密码、个人识别码。
但如果您愿意,可以直接在 Controller class 中使用 Order
实体。
我不建议这样做,但这是可能的。
我更喜欢像 Mapstruct 这样的 Mapper:
OrderDtoMapper mapper = new OrderDTOMapper();
Order order = OrderDtoMapper.map(orderDto, Order.class);
返回:
OrderDTO createdOrderDTO = OrderDtoMapper.map(order, OrderDTO.class);
对我而言,代码看起来更具可读性……而且您无需编写太多内容,因为 Mapstruct 会自动映射它。因为看起来你会映射很多 ;) 也许映射器值得一试:http://mapstruct.org/
总的来说,更喜欢DTO,因为single responsibility principle
,每个对象都有自己的责任,而且View/Controller和模型对象分开也更清楚
您有时可以减少 OrderDTO
,使用既是 DTD 又是真实对象的对象,
它将包括 DTD 属性以及您可以使用构建器添加的其他属性,例如,当根据请求创建对象时,我使用 @JsonIgnoreProperties(ignoreUnknown = true)
仅设置 DTD 属性,例如:
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(Include.NON_NULL)
public class Order
你也可以用JsonGetter/JsonProperty/JsonSetter来控制什么expected/returned
@JsonGetter and @JsonSetter are old alternatives to @JsonProperty.