将 Page<Entity> 转换为 PageDTO<EntityDTO>

8
我将使用Spring Data JPA进行翻译。
我的控制器如下所示:
    @RequestMapping(value = "/pages/{pageNumber}", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Page<User>> paginatedUser(@PathVariable final Integer pageNumber)
    {
        final PageRequest request = new PageRequest(pageNumber - 1, DEFAULt_PAGE_SIZE, Sort.Direction.DESC, "startTime");
        return new ResponseEntity<>(userRepository.findAll(request), HttpStatus.OK);
    }

现在,我决定发送一个 PageDTO 对象而不是 Page 对象,以限制发送的内容。我是否可以使用 Java 8 将 Page 转换为 PageDTO?

我看到 Page 是从 Iterable 导出的,所以我想我可以做一些像下面这样的事情,但是不确定如何将其与 PageDTO 和 UserDTO 结合起来。

StreamSupport.stream(userRepository.findAll(request).spliterator(),false)

有没有一种高效的 Java 8 方法来解决这个问题?我想出了以下解决方案。
     @RequestMapping(value = "/pages/{pageNumber}", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
     public ResponseEntity<PageDTO> paginatedUser(@PathVariable final Integer pageNumber)
        {
            final PageRequest request = new PageRequest(pageNumber - 1, DEFAULt_PAGE_SIZE, Sort.Direction.DESC, "startTime");
            final Page<User> page = userRepository.findAll(request);
            return new ResponseEntity<>(new PageDTO(page, StreamSupport.stream(page.getContent().spliterator(), true).map(UserDTO::new)
                    .collect(Collectors.toList())), HttpStatus.OK);
        }


public class PageDTO {

    private int beginIndex;

    private int currentIndex;

    private int endIndex;

    private List<?> entities;

    public PageDTO(final Page<?> page, final List<?> entities) {
        this.entities = entities;
        this.currentIndex = page.getNumber() + 1;
        this.beginIndex = Math.max(1, currentIndex - 5);
        this.endIndex = Math.min(beginIndex + 10, page.getTotalPages());
    }

想知道是否有其他更有效的方法来完成这个任务?


我认为这可能会对你有所帮助:https://dev59.com/1VkT5IYBdhLWcg3wG8D4 - Vivek Kurmi
2个回答

12

我知道这是一个老问题,但我遇到了同样的问题,我想为有兴趣的人提供可能的解决方案。以下是我发现的帮助我解决代码问题的内容: https://github.com/pkainulainen/spring-data-jpa-examples/blob/master/query-methods/src/main/java/net/petrikainulainen/springdata/jpa/todo/TodoMapper.java

我还使用了JpaRepository来分页数据,以便DTO页面具有相同的参数(页面编号,大小等)。以下是我的存储库:

@Repository
public interface Repository extends JpaRepository<Entity, Integer> {

    /**
     * Name the method according to what query you need to execute
     * e.g. findAll --> return all the rows that satisfy the following conditions,
     * ByUsername --> username is a field in entity class,
     * @param pageable: pagination is applied on the data.
     * @return 
     */
    public Page<Entity> findAllByUsername(String username, Pageable pageable);

}

这是我进行映射的方法:

public Page<EntityDTO> findByUsername(String username, Pageable pageable){
    Page<Entity> entityPage = entityRepository.findAllByUsername(username, pageable);
    List<EntityDTO> dtos = mapper.entityToEntityDTOs(entityPage.getContent());
    return new PageImpl<>(dtos, pageable, entityPage.getTotalElements());
}

我的Mapstruct映射器:

import org.mapstruct.factory.Mappers;

/**
 * Mapper for converting entity to DTO.
 */
@Mapper(componentModel = "spring", uses = {})
public interface Mapper {

    /**
     * The interface declares a member INSTANCE, providing clients access to the mapper implementation,
     * which is the file target\generated-sources\com\company\springapp\dto\mappers\MapperImpl.java
     * (automatically generated when compiling the project).
     */
    AuditMapper INSTANCE = Mappers.getMapper( Mapper.class );

    /**
     * Convert entity to DTO.
     * Mappings are used to 'bind' entity fields to DTO fields (for the mapper's implementation).
     * @param entity
     * @return 
     */
    @Mappings({
        @Mapping(source = "id", target = "id"),
        @Mapping(source = "username", target = "dtoUsername"),
        @Mapping(source = "action", target = "dtoAction")
    })
    public EntityDTO entityToEntityDTO(Entity entity);

    /**
     * Convert entities' list to DTOs' list.
     * @param entities
     * @return 
     */
    public List<EntityDTO> entitiesToEntityDTOs(List<Entity> entities);

}

我可以给+1000吗?我从没这么想过。 - w35l3y

1
这是一个晚了的答案,但这个解决方案对我有效。
服务
public Page<EntityDto> getAllEntities(Pageable pageable) {
    return entityRepository.findAll(pageable).map(entityMapper::toEntityDto);
}

映射器

import org.mapstruct.Mapper;

@Mapper(componentModel = "spring")
public interface EntityMapper {
    EntityDto toEntityDto(Entity entity);
}

控制器

@GetMapping(path = "/entities")
    public List<EntityDto> getAllEntities(Pageable pageable) {
        Page<EntityDto> page = entityService.getAllEntities(pageable);
        return page.getContent();
    }

这将返回第一页大小为10个实体的列表

http://localhost:port/api/entities?page=0&size=10

感谢JHipster!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接