【问题标题】:How to pass an "filter" object to spring data jpa repository to create a query如何将“过滤器”对象传递给 Spring Data JPA 存储库以创建查询
【发布时间】:2018-08-30 17:13:46
【问题描述】:

我需要将一个对象传递给 Spring Boot 端点(在 @RequestBody 中),并使用该对象使用 spring data jpa 查询数据库。

我的班级

@Entity(name = "PESSOA")
public class Pessoa {

private Long codigo;
private String nome;
private String cpf;
private String estadoCivil;
private LocalDate dataNascimento;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getCodigo() {
    return codigo;
}

@Column
public String getNome() {
    return nome;
}

@Column
public String getCpf() {
    return cpf;
}

@Column
public String getEstadoCivil() {
    return estadoCivil;
}

@Column
public LocalDate getDataNascimento() {
    return dataNascimento;
}

public void setCpf(String cpf) {
    this.cpf = cpf;
}

public void setEstadoCivil(String estadoCivil) {
    this.estadoCivil = estadoCivil;
}

public void setDataNascimento(LocalDate dataNascimento) {
    this.dataNascimento = dataNascimento;
}

public void setCodigo(Long codigo) {
    this.codigo = codigo;
}

public void setNome(String nome) {
    this.nome = nome;
}

}

这是包含我的端点的类:

@RestController
public class PessoaService {

@Autowired
private PessoaRepository pessoaRepository;

@GetMapping("/pessoa")
public List<Pessoa> all() {
    return pessoaRepository.findAll();
}


@GetMapping("/pessoa/{id}")
public Pessoa get(@PathVariable Long id) {
    return pessoaRepository.findById(id).get();
}

@PostMapping("/pessoa")
public Pessoa create(@RequestBody Pessoa pessoa) {
    return pessoaRepository.saveAndFlush(pessoa);
}

@PutMapping("/pessoa/{id}")
public Pessoa update(@PathVariable Long id, @RequestBody Pessoa pessoa) {
    Pessoa pessoaExistente = pessoaRepository.findById(id).get();
    BeanUtils.copyProperties(pessoa, pessoaExistente);
    return pessoaRepository.saveAndFlush(pessoaExistente);
}

@DeleteMapping("/pessoa/{id}")
public Pessoa delete(@PathVariable Long id) {
    Pessoa pessoaExistente = pessoaRepository.findById(id).get();
    pessoaRepository.delete(pessoaExistente);
    return pessoaExistente;
}

}

这是我的仓库:

@Repository
public interface PessoaRepository extends JpaRepository<Pessoa, Long> {

}

有一种方法可以创建类似的东西:

@GetMapping("/pessoa")
public List<Pessoa> filter(@RequestBody PessoaFilter filter) {
    return pessoaRepository.findByFilter(filter);
}

Spring 数据提供了可以像过滤器一样使用的东西?

【问题讨论】:

    标签: java spring spring-data-jpa


    【解决方案1】:

    您可以通过规范来做到这一点。见this tutorial on Spring's blog

    一旦您将接口添加到接受该方法的过滤版本的存储库,您所调用的 PessoaFilter 就会作为谓词传递到查询方法中。

    实现这个接口:

    public interface Specification<T> {
        Predicate toPredicate(Root<T> root, CriteriaQuery query, CriteriaBuilder cb);
    }
    

    可以在这里实现,例如:

    public interface PessoaSpecifications {
    
        static <Pessoa> Specification<Pessoa> byCpf(String someCpf) {
            return new Specification<Pessoa> {
                public Predicate toPredicate(Root<Pessoa> root, CriteriaQuery query, CriteriaBuilder cb) {
                    return cb.equal(root.get(Customer_.cpf), someCpf);
                }
            };
        }
    }
    

    并让您的存储库扩展 JpaSpecificationExecutor 以及之前扩展的任何内容。您将能够将您的规范传递到查询中:

    pessoaRepo.findAll(PessoaSpecifications.byCpf("asdf"));
    

    同一篇文章继续描述了使用Querydsl 的另一种方法,它避免了创建生成谓词的代码的麻烦。将 querydsl 插件添加到 pom.xml 并使用 QueryDslPredicateExecutor 扩展存储库接口后,您可以编写类似

    的内容
    List<Pessoa> p = pessoaRepo.findAll(pessoa.cpf.eq("asdf"));
    

    【讨论】:

      猜你喜欢
      • 2012-04-12
      • 2018-09-22
      • 1970-01-01
      • 2016-01-08
      • 2019-05-01
      • 2014-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多