应该在哪一层进行DTO /实体转换。
在Spring Mvc应用程序中具有以下结构:
我现在使用的方法,服务层为@Transactional
。
@RestController
public class ExampleController {
@Autowired
private ExampleService exampleService;
@Autowired
private ExampleMapper exampleMapper;
@GetMapping("/examples")
public ResponseEntity<List<ExamleDto>> getAll() {
var examples = exampleService.getAll();
return ResponseEntity.ok(exampleMapper.examplesToExampleDtos(examples));
}
@PostMapping("/examples")
public ResponseEntity<Void> create(@RequestBody @Valid ExampleCreateDto createDto) {
var example = exampleService.create(createDto)
return ResponseEntity.created(URI.create("examples/" + example.getId()).build();
}
// PUT, DELETE, ...
}
@Service
@Transactional
public class ExampleService {
@Autowired
private ExampleRepository exampleRepository;
@Autowired
private ExampleMapper exampleMapper;
public List<Examle> getAll() {
var examples = exampleRepository.findAll();
return examples;
}
public void create(ExampleDto exampleDto) {
var example = exampleMapper.asExample(exampleDto);
return exampleRepository.save(example);
}
}
public interface ExampleRepository extends JpaRepository<Example, Long> {
为什么选择这个方法:
服务层是事务性的,因此每当我们回到控制器时,所有更改都将被清空(例如版本字段)。
它使您考虑实体图,可以说您有一个包含部门清单的Person实体。可以说PersonDto还包含DeparmentDtos列表,它会强制您在操作之前获取所有装扮,否则您将在控制器层中遇到LazyInitializationException。我认为这是一件好事,因为如果您要在服务中执行映射,那么您将执行N + 1个查询(N是部门的数量)而没有意识到。
需要彼此执行业务任务的服务,而是在实体模型上而不是在DTO模型上工作,DTO模型可能具有一些验证(@ NotNull,@ Size等),仅当其来自时才被验证外部,但内部不应该应用所有验证。作为服务方法的一部分,仍将在服务层中检查业务规则。这里唯一的事情是,对于更新/创建服务,仍然通过传递实体的dtos iso进行通信。
我在这个主题上搜索了很多,但是找不到确切的答案。
在服务层中创建Transformer或帮助器类。
例如:
在服务包中创建帮助程序子包。
现在,创建一个Transformer.java。
public final class Transformer {
public static DTO convertEntityToDTO(Entity entity) {
DTO dto = new DTO();
dto.setSomething(entity.getSomething());
....
....
return dto;
}
public static Entity convertDTOToEntity(DTO dto) {
Entity entity = new Entity();
entity.setSomething(dto.getSomething());
....
....
return entity;
}
}
现在,ExampleController.java(仅显示一个示例):
@RestController
public class ExampleController {
@Autowired
private ExampleService exampleService;
@PostMapping("/examples")
public ResponseEntity<Void> create(@RequestBody @Valid ExampleDto exampleDto) {
exampleDto = exampleService.create(exampleDto);
return ResponseEntity.created(URI.create("examples/" + exampleDto.getId()).build();
}
}
修改您的ExampleService.java:
@Service
@Transactional
public class ExampleService {
@Autowired
private ExampleRepository exampleRepository;
public ExampleDto create(ExampleDto exampleDto) {
ExampleEntity exampleEntity = ExampleTransformer.convertDTOToEntity(exampleDto);
return ExampleTransformer.convertEntityToDTO(exampleRepository.save(exampleEntity));
}
}
ExampleTransformer.java:
public final class Transformer {
public static DTO convertEntityToDTO(ExampleEntity exampleEntity) {
ExampleDto exampleDto = new DTO();
exampleDto.setSomething(exampleEntity.getSomething());
....
....
return exampleDto;
}
public static Entity convertDTOToEntity(ExampleDto exampleDto) {
ExampleEntity exampleEntity = new ExampleEntity();
exampleEntity.setSomething(exampleDto.getSomething());
....
....
return exampleEntity;
}
}