Spring mvc-哪一层应将实体转换为dto(反之亦然)

问题描述 投票:1回答:1

应该在哪一层进行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进行通信。

我在这个主题上搜索了很多,但是找不到确切的答案。

java rest spring-mvc api-design dto
1个回答
0
投票
[转换应在服务层使用助手进行。

在服务层中创建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;   

        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.