如何在Spring Data REST项目中使用DTO?

如何在Spring Data REST项目中使用DTO?,第1张

如何在Spring Data REST项目中使用DTO?

Entities

实体必须实现Identifiable接口。例如:

@Entitypublic class Category implements Identifiable<Integer> {    @Id    @GeneratedValue    private final Integer id;    private final String name;    @oneToMany    private final Set<Product> products = new HashSet<>();    // skipped}@Entitypublic class Product implements Identifiable<Integer> {    @Id    @GeneratedValue    private final Integer id;    private final String name;    // skipped}

Projections

创建一个投影接口,存储库查询方法将返回:

public interface CategoryProjection {    Category getCategory();    Long getQuantity();}

这将是DTO的基础。在此示例中,DTO将代表a Category,而

Products
的数量属于它。

Repository methods

Create方法将返回投影:一个投影,一个DTO列表和一个DTO页面列表。

@RepositoryRestResourcepublic 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}

Relation
当Spring Data REST渲染对象时使用注释。

控制者

RepositoryRestController
其中添加自定义方法将满足DTO的请求:

@RepositoryRestController@RequestMapping("/categories")public class CategoryController {    @Autowired private CategoryRepo repo;    @Autowired private RepositoryEntitylinks links;    @Autowired private PagedResourcesAssembler<CategoryProjection> assembler;        @GetMapping("/{id}/dto")    public ResponseEntity<?> getDto(@PathVariable("id") Integer categoryId) {        CategoryProjection dto = repo.getDto(categoryId);        return ResponseEntity.ok(toResource(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));    }        @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);    }}

从存储库收到

Projections
时,我们必须先完成从Projection到DTO的转换,然后将其“包装”到ResourceSupport对象,然后再发送给客户端。为此,我们使用辅助方法
toResource
:创建一个新的DTO,为此对象创建必要的链接,然后Resource使用该对象及其链接创建一个新的。

Result

请参阅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"        }    }}

List of 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"        }    }}

Paged list of 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    }}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5432173.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存