programing

스프링 데이터레스트에서 페이지를 페이지로 매핑하는 방법

oldcodes 2023. 5. 4. 20:30
반응형

스프링 데이터레스트에서 페이지페이지로 매핑하는 방법

데이터베이스를 검색할 때PagingAndSortingRepository.findAll(Pageable)알겠습니다Page<ObjectEntity>하지만 저는 DTO를 엔티티가 아닌 고객에게 노출하고 싶습니다.생성자에 엔티티를 주입하는 것만으로 DTO를 생성할 수 있지만, 페이지 개체의 엔티티를 DTO에 매핑하려면 어떻게 해야 합니까?스프링 문서에 따르면 페이지는 읽기 전용 작업을 제공합니다.

또한 Java 8을 지원하지 않기 때문에 Page.map을 사용할 수 없습니다.매핑된 개체로 새 페이지를 수동으로 만드는 방법은 무엇입니까?

여전히 사용할 수 있습니다.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;
    }
});

Spring Data 2에서 페이지 맵 방법은 Converter 대신 Function을 사용하지만, 기본적으로 @Ali Dehhhani가 설명한 것과 동일하게 작동합니다.

기능 사용:

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;
    }
});

Java8의 경우:

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

여기서 fromEntity는 변환 로직을 포함하는 ObjectD의 정적 메서드입니다.

다음을 수행하여 Page.map을 사용할 수 있습니다.

public Page<ObjectDto> toPageObjectDto(Page<Object> objects) {
    Page<ObjectDto> dtos  = objects.map(this::convertToObjectDto);
    return dtos;
}

private ObjectDto convertToObjectDto(Object o) {
    ObjectDto dto = new ObjectDto();
    //conversion here
    return dto;
}

저는 모델 매퍼, 제네릭, 람다로 일반적인 사용을 위한 솔루션을 만들었고, 여러 프로젝트에서 매일 사용되고 있습니다.

/**
 * 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);

@Tip: util 클래스에서 이 메서드를 사용할 수 있으며, 아키텍처에 따라 서비스 및 컨트롤러의 페이지에서 모든 entity/dto 변환에 재사용할 수 있습니다.

예:

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

@Ali Dehhhani 덕분에 해결책이 있습니다.

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

        });
    }

람다 식을 사용하는 것이 더 편리합니다.

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

Page<OrderDTO> orderPage = persistedOrderPage.map(persistedOrder -> {
    OrderDTO order = mapper.toOrderDTO(persistedOrder);
    // do another action
    return order;
});

이는 스프링 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의 페이지 유형에서는 컨버터가 더 이상 지원되지 않습니다.또한 java.util.function에서 Function을 사용해야 합니다.기능.

Java 8 Lambda를 사용하여 저에게 효과가 있었습니다.답은 위에 이미 나와 있습니다. 저는 단순화하고 있습니다.

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


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

여기서 employeeEntityToDto()는 엔티티를 Dtos로 변환하는 메서드입니다.

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

람다를 모델맵퍼와 함께 사용했습니다.

    Page<ObjectEntity> pageEntity = objectRepository.findAll(pageable);
    Page<ObjectDto> pageDto = pageEntity.map(objectEntity -> modelMapper.map(objectEntity, ObjectDto.class));

마지막으로, 당신은 페이지를 사용자에게 돌려주지 않고, 헤더에 페이지 세부사항이 있는 ObjectDTO 목록을 반환할 것이므로, 이것이 나의 해결책이 될 것입니다.

개체 서비스

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

개체 리소스 / 나머지(노출된 끝점)

@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에 대한 페이지 세부 정보를 복제할 필요가 없기 때문입니다.페이지에는 다음이 포함되어 있습니다.

  • 페이지 번호
  • 페이지 크기
  • 요소 수
  • 내용물

컨텐츠는 반환된 개체 목록이며 DTO에 매핑해야 하는 유일한 항목입니다.

언급URL : https://stackoverflow.com/questions/39036771/how-to-map-pageobjectentity-to-pageobjectdto-in-spring-data-rest

반응형