如何使用Spring Data JPA实现对可选字段的搜索?

时间:2018-07-19 13:17:21

标签: search dynamic spring-data-jpa

如何使用Spring数据JPA实现对可选字段的搜索?我已经在多个地方进行了研究,但没有任何帮助。

1 个答案:

答案 0 :(得分:0)

经过一段时间的反复试验,我得以实现对可选字段的搜索。

1st)我使用JpaSpecificationExecutor接口扩展了存储库

package br.mp.mpce.sge.repository;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;

import br.mp.mpce.sge.domain.Documento;
import br.mp.mpce.sge.domain.Setor;

@Repository
public interface DocumentoRepository extends JpaRepository<Documento, Integer>, JpaSpecificationExecutor<Documento> {

    Page<Documento> findPageBySetorCadastro(Setor setor, Pageable pageRequest);

}

2)我实现了根据搜索参数返回“规格”的方法。

package br.mp.mpce.sge.specifications;

import java.time.LocalDateTime;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.data.jpa.domain.Specification;

import br.mp.mpce.sge.domain.Documento;
import br.mp.mpce.sge.domain.Setor;

public final class DocumentoSpecification {

    public static Specification<Documento> byCodigo(Integer codigo) {
        return new Specification<Documento>() {

            private static final long serialVersionUID = -4943925466558950754L;

            @Override
            public Predicate toPredicate(Root<Documento> root, CriteriaQuery<?> query,
                    CriteriaBuilder criteriaBuilder) {
                return criteriaBuilder.equal(root.get("codigo"), codigo);
            }

        };
    }

    public static Specification<Documento> byAno(String ano) {
        return new Specification<Documento>() {

            private static final long serialVersionUID = 8333055743400529192L;

            @Override
            public Predicate toPredicate(Root<Documento> root, CriteriaQuery<?> query,
                    CriteriaBuilder criteriaBuilder) {
                return criteriaBuilder.equal(root.get("ano"), ano);
            }

        };
    }

    public static Specification<Documento> byDataInicial(LocalDateTime dataInicial) {
        return new Specification<Documento>() {

            private static final long serialVersionUID = -9172458840598392417L;

            @Override
            public Predicate toPredicate(Root<Documento> root, CriteriaQuery<?> query,
                    CriteriaBuilder criteriaBuilder) {
                return criteriaBuilder.greaterThanOrEqualTo(root.get("dataCadastro"), dataInicial);
            }

        };
    }

    public static Specification<Documento> byDataFinal(LocalDateTime dataFinal) {
        return new Specification<Documento>() {

            private static final long serialVersionUID = 1422089735211883866L;

            @Override
            public Predicate toPredicate(Root<Documento> root, CriteriaQuery<?> query,
                    CriteriaBuilder criteriaBuilder) {
                return criteriaBuilder.lessThanOrEqualTo(root.get("dataCadastro"), dataFinal);
            }

        };
    }

    public static Specification<Documento> bySetor(Setor setor) {
        return new Specification<Documento>() {

            private static final long serialVersionUID = -2336742358257555013L;

            @Override
            public Predicate toPredicate(Root<Documento> root, CriteriaQuery<?> query,
                    CriteriaBuilder criteriaBuilder) {
                return criteriaBuilder.equal(root.get("setorCadastro"), setor);
            }

        };
    }
}

3º)我实现了服务方法类。

public Page<Documento> findByFields(Integer codigo, String ano, String dataInicio, String dataFinal, Integer page,
            Integer lines, String direction, String orderBy) {
        UsuarioSS usuarioSS = UsuarioServiceImpl.authenticated();
        if (usuarioSS == null) {
            throw new PersonalizedAutorizationException("Acesso negado - Usuario deve estar autenticado");
        }

        Usuario usuario = usuarioService.findById(usuarioSS.getId());
        PageRequest pageRequest = PageRequest.of(page, lines, Direction.fromString(direction), orderBy);

        Specification<Documento> specification = DocumentoSpecification.bySetor(usuario.getSetor());

        if (codigo != null) {
            specification = specification.and(DocumentoSpecification.byCodigo(codigo));
        }

        if (ano != null) {
            specification = specification.and(DocumentoSpecification.byAno(ano));
        }
        if (dataInicio != null) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            LocalDate localDateInicio;
            localDateInicio = LocalDate.parse(dataInicio, formatter);
            LocalDateTime localDateTimeInicio = localDateInicio.atStartOfDay();
            specification = specification.and(DocumentoSpecification.byDataInicial(localDateTimeInicio));
        }
        if (dataFinal != null) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            LocalDate localDateFinal;
            localDateFinal = LocalDate.parse(dataFinal, formatter);
            LocalDateTime localDateTimeFinal = localDateFinal.atStartOfDay();
            specification = specification.and(DocumentoSpecification.byDataFinal(localDateTimeFinal));
        }

        Page<Documento> pageDoc = documentoRepository.findAll(specification, pageRequest);

        if (pageDoc.getContent().isEmpty()) {
            throw new PersonalizedObjectNotFoundException(super.messageSource.getMessage("error.notFound",
                    new String[] { super.messageSource.getMessage(
                            StringUtils.uncapitalize(super.getEntityClass().getSimpleName()), null,
                            StringUtils.uncapitalize(getEntityClass().getSimpleName()), null) },
                    "error.notFound", null));
        }

        return pageDoc;

    }

4º)在restcontroller中实现了搜索方法。

@RequestMapping(value = "/search", method = RequestMethod.GET)
    public ResponseEntity<Page<Documento>> findPageByFields(
            @RequestParam(value = "codigo", required = false) Integer codigo,
            @RequestParam(value = "ano", required = false) String ano,
            @RequestParam(value = "dataInicio", required = false) String dataInicio,
            @RequestParam(value = "dataFinal", required = false) String dataFinal,
            @RequestParam(value = "page", defaultValue = "0") Integer page,
            @RequestParam(value = "lines", defaultValue = "10") Integer lines,
            @RequestParam(value = "direction", defaultValue = "DESC") String direction,
            @RequestParam(value = "orderBy", defaultValue = "dataCadastro") String orderBy) {
        Page<Documento> pageDocumento = documentoService.findByFields(codigo, ano, dataInicio, dataFinal, page, lines,
                direction, orderBy);
        return ResponseEntity.ok().body(pageDocumento);
    }