如何在Spring-data-rest中将Page <objectentity>映射到Page <objectdto>

时间:2016-08-19 10:30:56

标签: java spring spring-mvc spring-data spring-data-rest

当我使用PagingAndSortingRepository.findAll(Pageable)点击数据库时,我得到Page<ObjectEntity>。但是,我想将DTO公开给客户而不是实体。我可以通过将实体注入到它的构造函数中来创建DTO,但是如何将Page对象中的实体映射到DTO&#39; s?根据spring文档,Page提供了只读操作。

此外,Page.map不可能,因为我们不支持java 8.如何手动创建带有映射对象的新页面?

9 个答案:

答案 0 :(得分:36)

你仍然可以使用没有lambda表达式的Page.map

Page<ObjectEntity> entities = objectEntityRepository.findAll(pageable);
Page<ObjectDto> dtoPage = entities.map(new Converter<ObjectEntity, ObjectDto>() {
    @Override
    public ObjectDto convert(ObjectEntity entity) {
        ObjectDto dto = new ObjectDto();
        // Conversion logic

        return dto;
    }
});

答案 1 :(得分:5)

在Spring Data 2中,Page map方法使用Function而不是Converter,但它仍然与@Ali Dehghani所描述的基本相同。

使用功能:

Page<ObjectEntity> entities = objectEntityRepository.findAll(pageable);
Page<ObjectDto> dtoPage = entities.map(new Function<ObjectEntity, ObjectDto>() {
    @Override
    public ObjectDto apply(ObjectEntity entity) {
        ObjectDto dto = new ObjectDto();
        // Conversion logic

        return dto;
    }
});

答案 2 :(得分:3)

这是我的解决方案,感谢@Ali Dehghani

private Page<ObjectDTO> mapEntityPageIntoDTOPage(Page<ObjectEntity> objectEntityPage) {
        return objectEntityPage.map(new Converter<ObjectEntity, ObjectDTO>() {
            public ObjectDTO convert(ObjectEntity objectEntity) {
                return new ObjectDTO(objectEntity, httpSession);
            }

        });
    }

答案 3 :(得分:2)

在java8中:

Page<ObjectEntity> entities = 
 objectEntityRepository.findAll(pageable)
 .map(ObjectDto::fromEntity);

其中fromEntity是ObjectDto上包含转换逻辑的静态方法。

答案 4 :(得分:2)

我已创建并使用具有模型映射器,泛型和lambda的解决方案以用于常见用途。

/**
 * Maps the Page {@code entities} of <code>T</code> type which have to be mapped as input to {@code dtoClass} Page
 * of mapped object with <code>D</code> type.
 *
 * @param <D> - type of objects in result page
 * @param <T> - type of entity in <code>entityPage</code>
 * @param entities - page of entities that needs to be mapped
 * @param dtoClass - class of result page element
 * @return page - mapped page with objects of type <code>D</code>.
 * @NB <code>dtoClass</code> must has NoArgsConstructor!
 */
public <D, T> Page<D> mapEntityPageIntoDtoPage(Page<T> entities, Class<D> dtoClass) {
    return entities.map(objectEntity -> modelMapper.map(objectEntity, dtoClass));
} 

这正是您需要的情况(我认为其他情况也很常见)。

您已经通过这种方式从存储库获取数据(与服务相同):

Page<ObjectEntity> entities = objectEntityRepository.findAll(pageable);

转换所需的一切都是以这种方式调用此方法:

Page<ObjectDto> dtoPage = mapEntityPageIntoDtoPage(entities, ObjectDto.class);

@提示:您可以从util类使用此方法,并且可以根据您的体系结构在服务和控制器上的Page转换中将其重用于所有实体/ dto。

示例:

Page<ObjectDto> dtoPage = mapperUtil.mapEntityPageIntoDtoPage(entities, ObjectDto.class);

答案 5 :(得分:1)

这在Spring 2.0中正常工作-

@Override
public Page<BookDto> getBooksByAuthor(String authorId, Pageable pageable) {
        Page<BookEntity> bookEntity = iBookRepository.findByAuthorId(authorId, pageable);
        return bookEntity.map(new Function<BookEntity, BookDto>() {

            @Override
            public BookDto apply(BookEntity t) {
                return new ModelMapper().map(t, BookDto.class);
            }

        });
    }

Spring 2.0的Page类型不再支持该转换器。另外,应从java.util.function.Function中使用此Function。

答案 6 :(得分:0)

最后,您不会将页面返回给用户,而是返回一个ObjectDTO列表,页面上的页面详细信息,这将是我的解决方案。

ObjectService

public Page<ObjectEntity> findAll (Pageable pageable){
  //logic goes here.
  Page<ObjectEntity> page = objectRepository.findAll(pageable);
  return page;
} 

ObjectResource / rest(暴露的端点)

@GetMapping
public ResponseEntity<List<ObjectDTO>> findAll (Pageable pageable){
  Page<ObjectEntity> page = objectServiceService.findAll(pageable);

  HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "your-endpoint-here");

  return new ResponseEntity<>(objectMapper.toDto(page.getContent()), headers, HttpStatus.OK);
}

使用它的原因是您不需要复制ObjectEntity和DTO的页面详细信息。值得注意的是,页面包含以下内容:

  • 页码
  • pageSize
  • numberOfElements
  • 含量

内容是返回的对象列表,是唯一需要映射到DTO的内容。

答案 7 :(得分:0)

使用lambda表达式更方便

Page<ObjectDto> dto=objectRepository.findAll(pageable).map((object -> DozerBeanMapperBuilder.buildDefault().map(object, ObjectDto.class)));

答案 8 :(得分:0)

使用 Java 8 Lambda,它对我有用。上面已经给出了答案,我只是在简化。

Page<EmployeeEntity> employeeEntityPage = employeeService.findEmployeeEntities();


Page<EmployeeDto> employeeDtoPage = employeeEntityPage.map(entity -> {
        EmployeeDto dto = employeeService.employeEntityToDto(entity);
        return dto;
    });

这里employeeEntityToDto()是将Entities转换为Dtos的方法

public EmployeeDto employeeEntityToDto(EmployeeEntity entity){
    EmployeeDto employeeDto =  new EmployeeDto();
    employeeDto.setId(entity.getId());
    employeeDto.setName(entity.getName());
    return employeeDto;
}