[SPRING] 스프링 데이터 REST 프로젝트에서 DTO를 사용하는 방법은 무엇입니까?
SPRING스프링 데이터 REST 프로젝트에서 DTO를 사용하는 방법은 무엇입니까?
스프링 데이터 REST는 도메인 객체 만 노출하는 것을 자동화합니다. 하지만 대부분의 경우 데이터 전송 객체를 처리해야합니다. 어떻게 SDR 방식으로이 작업을 수행 할 수 있습니까?
해결법
-
==============================
1.Spring Data REST 프로젝트에서 DTO를 사용하는 방법에 대한 접근법
Spring Data REST 프로젝트에서 DTO를 사용하는 방법에 대한 접근법
작업 예제는 여기에 있습니다.
개체
엔티티는 Identifiable 인터페이스를 구현해야합니다. 예 :
@Entity public class Category implements Identifiable<Integer> { @Id @GeneratedValue private final Integer id; private final String name; @OneToMany private final Set<Product> products = new HashSet<>(); // skipped } @Entity public class Product implements Identifiable<Integer> { @Id @GeneratedValue private final Integer id; private final String name; // skipped }
투영법
저장소 쿼리 메소드가 반환 할 투영 인터페이스를 만듭니다.
public interface CategoryProjection { Category getCategory(); Long getQuantity(); }
그것은 DTO의 기반이 될 것입니다. 이 예에서 DTO는 카테고리를 나타내고 제품 수는 그 카테고리에 속합니다.
저장소 메소드
Create 메소드는 투영법을 반환합니다. 하나는 DTO 목록이고 다른 하나는 DTO 목록입니다.
@RepositoryRestResource public interface CategoryRepo extends JpaRepository<Category, Integer> { @RestResource(exported = false) @Query("select c as category, count(p) as quantity from Category c join c.products p where c.id = ?1 group by c") CategoryProjection getDto(Integer categoryId); @RestResource(exported = false) @Query("select c as category, count(p) as quantity from Category c join c.products p group by c") List<CategoryProjection> getDtos(); @RestResource(exported = false) @Query("select c as category, count(p) as quantity from Category c join c.products p group by c") Page<CategoryProjection> getDtos(Pageable pageable); }
DTO
인터페이스에서 DTO 구현 :
@Relation(value = "category", collectionRelation = "categories") public class CategoryDto implements CategoryProjection { private final Category category; private final Long quantity; // skipped }
Annotation Relation은 Spring Data REST가 객체를 렌더링 할 때 사용된다.
제어 장치
DTO 요청을 처리 할 사용자 정의 메소드를 RepositoryRestController에 추가하십시오.
@RepositoryRestController @RequestMapping("/categories") public class CategoryController { @Autowired private CategoryRepo repo; @Autowired private RepositoryEntityLinks links; @Autowired private PagedResourcesAssembler<CategoryProjection> assembler; /** * Single DTO */ @GetMapping("/{id}/dto") public ResponseEntity<?> getDto(@PathVariable("id") Integer categoryId) { CategoryProjection dto = repo.getDto(categoryId); return ResponseEntity.ok(toResource(dto)); } /** * List of DTO */ @GetMapping("/dto") public ResponseEntity<?> getDtos() { List<CategoryProjection> dtos = repo.getDtos(); Link listSelfLink = links.linkFor(Category.class).slash("/dto").withSelfRel(); List<?> resources = dtos.stream().map(this::toResource).collect(toList()); return ResponseEntity.ok(new Resources<>(resources, listSelfLink)); } /** * Paged list of DTO */ @GetMapping("/dtoPaged") public ResponseEntity<?> getDtosPaged(Pageable pageable) { Page<CategoryProjection> dtos = repo.getDtos(pageable); Link pageSelfLink = links.linkFor(Category.class).slash("/dtoPaged").withSelfRel(); PagedResources<?> resources = assembler.toResource(dtos, this::toResource, pageSelfLink); return ResponseEntity.ok(resources); } private ResourceSupport toResource(CategoryProjection projection) { CategoryDto dto = new CategoryDto(projection.getCategory(), projection.getQuantity()); Link categoryLink = links.linkForSingleResource(projection.getCategory()).withRel("category"); Link selfLink = links.linkForSingleResource(projection.getCategory()).slash("/dto").withSelfRel(); return new Resource<>(dto, categoryLink, selfLink); } }
저장소에서 투영을 수신 할 때 프로젝션에서 DTO 로의 최종 변환을해야합니다 클라이언트에 보내기 전에 ResourceSupport 객체에 '포장'합니다. 이를 위해 우리는 helper method toResource를 사용합니다 : 새로운 DTO를 만들고,이 객체에 필요한 링크를 만들고, 그 다음에 객체와 그 링크로 새로운 Resource를 생성하십시오.
결과
Postman 사이트의 API 문서를 참조하십시오.
Singe DTO
GET http://localhost:8080/api/categories/6/dto
{ "category": { "name": "category1" }, "quantity": 3, "_links": { "category": { "href": "http://localhost:8080/api/categories/6" }, "self": { "href": "http://localhost:8080/api/categories/6/dto" } } }
DTO 목록
GET http://localhost:8080/api/categories/dto
{ "_embedded": { "categories": [ { "category": { "name": "category1" }, "quantity": 3, "_links": { "category": { "href": "http://localhost:8080/api/categories/6" }, "self": { "href": "http://localhost:8080/api/categories/6/dto" } } }, { "category": { "name": "category2" }, "quantity": 2, "_links": { "category": { "href": "http://localhost:8080/api/categories/7" }, "self": { "href": "http://localhost:8080/api/categories/7/dto" } } } ] }, "_links": { "self": { "href": "http://localhost:8080/api/categories/dto" } } }
DTO의 페이지 목록
GET http://localhost:8080/api/categories/dtoPaged
{ "_embedded": { "categories": [ { "category": { "name": "category1" }, "quantity": 3, "_links": { "category": { "href": "http://localhost:8080/api/categories/6" }, "self": { "href": "http://localhost:8080/api/categories/6/dto" } } }, { "category": { "name": "category2" }, "quantity": 2, "_links": { "category": { "href": "http://localhost:8080/api/categories/7" }, "self": { "href": "http://localhost:8080/api/categories/7/dto" } } } ] }, "_links": { "self": { "href": "http://localhost:8080/api/categories/dtoPaged" } }, "page": { "size": 20, "totalElements": 2, "totalPages": 1, "number": 0 } }
from https://stackoverflow.com/questions/45401734/how-to-work-with-dto-in-spring-data-rest-projects by cc-by-sa and MIT license