Cep*_*pr0 11 spring projection dto spring-data-rest
Spring Data REST自动仅公开域对象.但大多数情况下,我们必须处理数据传输对象.那么如何以SDR方式做到这一点?
Cep*_*pr0 26
如何在Spring Data REST项目中使用DTO的方法
工作的例子在这里
实体
实体必须实现可识别的接口.例如:
@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
}
Run Code Online (Sandbox Code Playgroud)
预测
创建存储库查询方法将返回的投影接口:
public interface CategoryProjection {
Category getCategory();
Long getQuantity();
}
Run Code Online (Sandbox Code Playgroud)
它将是DTO的地下室.在此示例中,DTO将表示a Category并且Products 的数量属于它.
存储库方法
创建方法返回投影:单个,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);
}
Run Code Online (Sandbox Code Playgroud)
DTO
从其界面实现DTO:
@Relation(value = "category", collectionRelation = "categories")
public class CategoryDto implements CategoryProjection {
private final Category category;
private final Long quantity;
// skipped
}
Run Code Online (Sandbox Code Playgroud)
RelationSpring Data REST渲染对象时使用注释.
调节器
添加自定义方法RepositoryRestController将为DTO的请求提供服务:
@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);
}
}
Run Code Online (Sandbox Code Playgroud)
当从存储库收到预测时,我们必须从Projection到DTO进行最终转换,并在发送到客户端之前将其"换行"到ResourceSupport对象.为此,我们使用辅助方法toResource:我们创建一个新的DTO,为该对象创建必要的链接,然后Resource使用该对象及其链接创建一个新的.
结果
请参阅Postman网站上的API文档
烧STO
GET http://localhost:8080/api/categories/6/dto
Run Code Online (Sandbox Code Playgroud)
{
"category": {
"name": "category1"
},
"quantity": 3,
"_links": {
"category": {
"href": "http://localhost:8080/api/categories/6"
},
"self": {
"href": "http://localhost:8080/api/categories/6/dto"
}
}
}
Run Code Online (Sandbox Code Playgroud)
DTO列表
GET http://localhost:8080/api/categories/dto
Run Code Online (Sandbox Code Playgroud)
{
"_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"
}
}
}
Run Code Online (Sandbox Code Playgroud)
DTO的分页列表
GET http://localhost:8080/api/categories/dtoPaged
Run Code Online (Sandbox Code Playgroud)
{
"_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
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10260 次 |
| 最近记录: |