【问题标题】:Creating JPA query with Date in Spring在 Spring 中使用 Date 创建 JPA 查询
【发布时间】:2018-07-01 03:18:06
【问题描述】:

这是我的实体的样子:

@Entity
public class Registration {
@Id
@GeneratedValue
private Integer id;

@org.springframework.format.annotation.DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate date;
}

这就是我的仓库的样子:

@Query(value = "SELECT * FROM registration WHERE MONTH(date) = ?1 AND YEAR(date) = ?2")
List<Registration> findAll(Integer month, Integer year);

这将是服务:

public List<Registration> getCurrentRegistration() {
    LocalDate today = LocalDate.now();
    return registrationRepository.findAll(today.getMonth().getValue(), today.getYear());
}
public List<Registration> getRegistrations(Integer month, Integer year) {
    return registrationRepository.findAll(month, year);
}

如何将我的本机查询更改为 JPA 查询? JPA 查询能否在 postgresql 和 hsqldb 上工作? 为什么 JPA 查询最适合 Spring 应用程序? (或者为什么他们不是)

【问题讨论】:

  • 您的 JPA 提供程序是否支持函数 MONTHYEAR ?因为它们不是标准的 JPA 函数。当您查看 JPA 的文档时,您尝试过什么?
  • 我还没有尝试太多。我注意到我的解决方案(本机查询适用于 hsqldb,不适用于 postgresql)。我是 JPA 的新手,这就是我问你的原因。通常我只是使用 CRUD 或 JPA 存储库创建查询,例如 FindByName(String name);等等。这就是为什么我的知识是非常基础的。

标签: java spring postgresql spring-data-jpa jpql


【解决方案1】:

创建一个规范类,并在其中编写以下规范方法。

import javax.persistence.criteria.Predicate;
import org.springframework.data.jpa.domain.Specification;

public class RegistrationSpecification {
public static Specification<Registration > registrationSpecForDate(
      LocalDate invoiceDate ) {
    return (root, cq, cb) -> {

      List<Predicate> predicates = new ArrayList<Predicate>();

      if (invoiceDate!=(null)) {
          predicates.add(cb.greaterThanOrEqualTo(root.get("date"), 
           invoiceDate));
        }

      return cb.and(predicates.toArray(new Predicate[0]));
    };
  }

然后在您的存储库中将该规范注入 JPA 的 findAll() 方法中。

`public List<Registration> getRegistrations(LocalDate date) {
  return 
       registrationRepository.findAll
           (RegistrationSpecification.registrationSpecForDate(date));

`

【讨论】:

  • 你能说一下库谓词是什么类型的吗?我的意思是我需要什么样的导入(或者依赖)。
  • 请检查我的答案再次通过添加导入重新发布。
【解决方案2】:

您可以使用 QueryDSL JPA (https://github.com/querydsl/querydsl/tree/master/querydsl-jpa) 来定义谓词:

Predicate createPredicate(Integer month, Integer year) {
    return QRegistration.date.year().eq(year).and(QRegistration.date.month().eq(month));
}

然后让你的 repo 扩展 QueryDslPredicateExecutor:

public interface RegistrationRepository extends JpaRepository<Registration>, QueryDslPredicateExecutor {
  // Your query methods here
}

这包含一个List&lt;T&gt; findAll(Predicate predicate) 方法,您可以将谓词传递给该方法以获取您所追求的项目,例如:

registrationRepository.findAll(createPredicate(1, 1970));

有关在 Spring 中使用 QueryDSL 的更多信息,请参见此处:https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-15
    • 2016-08-23
    • 1970-01-01
    • 2020-02-08
    • 2019-09-25
    • 2017-11-25
    相关资源
    最近更新 更多