【问题标题】:Spring Data JPA Specifications CallingSpring Data JPA 规范调用
【发布时间】:2019-05-25 11:48:22
【问题描述】:

我按照本教程获取 Spring Data JPA 规范:https://dzone.com/articles/using-spring-data-jpa-specification

它为我实现了这一点,但我无法调用规范方法来搜索它们。我想把它们放在我的 SearchController 中:

代码: Telefonbuch 规格:

public static Specification<Telefonbuch> hasVorname(String vorname) {
    return (root, query, cb) -> {
        return cb.equal(root.get(Telefonbuch_.vorname), "%"+vorname.toLowerCase()+"%");
    };
}

现在我想在我的 SearchController (SucheController) 中调用这个方法,但我不知道怎么做。 目前该方法如下所示: 苏车控制器:

   public void search(String vorname, String nachname, String telefonnummer, String handynummer) {  
    telefonbuch.setVorname(vorname);
    telefonbuch.setNachname(nachname);
    telefonbuch.setTelefonnummer(telefonnummer);
    telefonbuch.setHandynummer(handynummer);

    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<Telefonbuch> query = builder.createQuery(Telefonbuch.class);
    Root<Telefonbuch> root = query.from(Telefonbuch.class);
    List<Predicate> predicates = new ArrayList<Predicate>();



    if (!vorname.isEmpty()) {   
        //eintraege = telefonbuchRepository.findAll(hasVorname()); -> does not work
        Predicate condition = builder.like(builder.lower(root.get(Telefonbuch_.vorname)), "%"+vorname.toLowerCase()+"%");
        predicates.add(condition);
    }
...
query.select(root).where(predicates.toArray(new Predicate[predicates.size()]));

【问题讨论】:

  • 您必须使用 JPA 存储库。查看 CustomerRepository dzone.com/articles/using-spring-data-jpa-specification
  • 我在“TelefonbuchRepository”中使用 JPA 存储库:公共接口 TelefonbuchRepository extends JpaRepository
  • 但是你注释掉了这一行。什么不起作用?
  • SucheController 的方法未定义。我可以称它为 TelefonbuchSpecifications.hasVorname(...) 但不是别的。即使我这样称呼它,我也不知道如何像谓词一样使用它来拥有它的条件

标签: java spring spring-data-jpa jpa-criteria


【解决方案1】:

您需要有一个 TelefonbuchRepository 接口,该接口实现了JpaRepositoryJpaSpecificationExecutor。后者为您提供方法,您可以将 Specification 传递给这些方法:

 - long     count(Specification<T> spec) 
 - List<T>  findAll(Specification<T> spec) 
 - Page<T>  findAll(Specification<T> spec, Pageable pageable)
 - List<T>  findAll(Specification<T> spec, Sort sort) 
 - Optional<T> findOne(Specification<T> spec)

编辑:我的规范:

public class MyEntitySpecification implements Specification<MyEntity> {

   private final String searchText;

   public MyEntitySpecification(String searchText) {
      this.searchText = searchText;
   }

   @Override
   public Predicate toPredicate(Root<MyEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
      List<Predicate> predicates = new ArrayList<>();
      Optional.ofNullable(searchText).ifPresent(
         s -> predicates.add(cb.like(cb.lower(root.get(MyEntity_.searchString)), "%" + s.toLowerCase() + "%"))
      );
      return cb.and(predicates.toArray(new Predicate[predicates.size()]));
   }
}

【讨论】:

  • 现在我打电话给 telefonbuchRepository.findAll(TelefonbuchSpecifications.hasVorname(vorname)) 但它不会给我任何东西
  • 检查正在生成的底层 SQL。我还会在我的答案中添加我如何生成我的Specification。 HTH。在您的第一个代码中,您使用 cb.equal 这是错误的。在您的第二个 sn-p 中,您使用的 builder 和我一模一样。
  • 抱歉,这不是正确的方法。我不知道为什么这不起作用:dzone.com/articles/using-spring-data-jpa-specification 我不能使用 findAll 方法,因为它告诉我: JpaRepository 类型中的方法 findAll(Sort) 不适用于参数( Specification) 但是为什么在给出规范时他认为它是排序?他甚至向我展示了 .findAll (Specification spec)
  • 你能看看这个吗? Question或许你能帮帮我。
猜你喜欢
  • 2016-07-22
  • 2016-02-17
  • 2017-01-12
  • 1970-01-01
  • 1970-01-01
  • 2012-08-15
  • 1970-01-01
  • 2017-10-28
  • 2020-05-20
相关资源
最近更新 更多