web-dev-qa-db-fra.com

Convertir le type de contenu Spring Data JPA

J'utilise Spring Data JPA et j'ai un PagingAndSortingRepository<Contact, Long> qui utilise un JPASpecificationExecutor<Contact>. Je passe une instance Specification et une instance Pageable à la méthode .findAll() de ce référentiel pour obtenir un Page<Contact>.

Cependant, mon entité Contact possède de nombreux champs et mappages supplémentaires dont je n’ai pas besoin sur le front-end. Donc, j'ai une ContactDto qui ne contient que les champs nécessaires et une méthode qui permet de convertir de Contact à ContactDto.

private ContactDto convertToContactDto(Contact contact) {
    //do the conversion
}

Comment pourrais-je utiliser cette méthode de conversion pour convertir le Page<Contact> en un Page<ContactDto>?

Je peux obtenir le contenu du Page<Contact> et faire la conversion comme ceci.

final Page<Contact> contactPage = pagingAndSortingContactRepository
        .findAll(ContactSpecification.findByFirstNmLike(firstNm), pageable);

final Collection<ContactDto> contactDtos = contactPage.getContent()
    .stream()
    .map(this::convertToContactDto)
    .collect(Collectors.toList());

Mais alors il me reste une Collection au lieu de Page, et je ne sais pas comment insérer cette Collection dans le contenu de Page Y a-t-il un moyen de faire cela? Ou existe-t-il un autre moyen d'appeler la conversion sur l'instance Page<Contact> elle-même?

22
Andrew Mairose

Il s'avère que Page a sa propre méthode .map(), à laquelle vous pouvez transmettre une référence de méthode pour effectuer la conversion.

Voici comment j'ai fini par faire la conversion.

final Page<ContactDto> contactDtoPage = contactPage.map(this::convertToContactDto);

La méthode convertToContactDto crée et retourne simplement une instance de la classe à laquelle je tente de me convertir:

private ContactDto convertToContactDto(final Contact contact) {
    final ContactDto contactDto = new ContactDto();
    //get values from contact entity and set them in contactDto
    //e.g. contactDto.setContactId(contact.getContactId());
    return contactDto;
}
44
Andrew Mairose

Il se peut qu'une transformation de page soit moins efficace pour effectuer une opération itérative, comme le ferait probablement Page.map(..), qu'avec l'ensemble de la collection.

Dans ce cas, nous pouvons utiliser la variable PageExecutionUtils de Spring pour reconstruire une page avec le contenu transformé.

public Page<TypeB> getPageAsTypeB(Pageable pageable) {
    Page<TypeA> pageA = pagingAndSortingContactRepository(pageable);
    Function<List<TypeA>, List<TypeB>> collectionTransform;

    Page<TypeB> pageB = PageableExecutionUtils.getPage(
        collectionTransform.apply(pageA.getContent()),
        pageable,
        pageA::getTotalElements);
    return pageB;
}
0
spaceman spiff