【问题标题】:JPA/Hibernate Custom Queries with optional parameters带有可选参数的 JPA/Hibernate 自定义查询
【发布时间】:2018-04-27 11:47:28
【问题描述】:

我有一个实体

@Entity
@Table(name = "EVENT")
public class Event {

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    private Long id;

    @Column(name = "EVENT", columnDefinition="VARCHAR(100)", nullable = false)
    private String event;

    @Column(name = "DATE", columnDefinition="DATETIME", nullable = false)
    @Convert(converter = InstantConverter.class)
    private Instant date;
}

还有一个SearchParams所有字段都是可选的

public class SearchParams {
    private Long id;
    private Instant startDate;
    private Instant endDate;
    private String event;

    public Optional<Long> getID() {
        return Optional.ofNullable(id);
    }
    // ... Similar for other fields ...
}

我希望能够像这样搜索:

public List<Event> search(SearchParams searchParams) {
    // Do something with Entity Manager/another hibernate class to create a custom query based off the search params.
    return events;
}

在 JPA 中实现这一目标的最简单方法是什么?或者这不是使用正确的框架?

我总是可以求助于sql 字符串构建,但这不是一个好方法。

【问题讨论】:

  • 如何将SearchParams 类字段保存到数据库中
  • 我认为这篇文章会有所帮助。 stackoverflow.com/questions/2444603/…
  • @ArvindKatte 我没有持久化该对象,它纯粹是一个包含要在 where 子句中使用的搜索过滤器的类,例如,如果 SearchParams 具有填充数据库查询的 event 字段将选择事件字段与过滤器匹配的行
  • 我在这里解释了解决方案,可能对你有帮助stackoverflow.com/a/48854352/4720910

标签: java jpa


【解决方案1】:

据记得 JPA 有 where 方法,它将 Predicates 数组作为参数。

所以你可以做的是从你的参数创建动态的谓词列表,然后将它传递给你的查询。

所以你的代码会是这样的

List<Predicate> predicates= new ArrayList<>();
if (!searchParams.getId().isEmpty()){
predicates.add(cb.equal(root.get("id"), searchParams.getId());
}
....
query.where(predicates.toArray(new Predicate[predicates.size()]));

【讨论】:

    【解决方案2】:

    Spring Data JPA 示例查询技术使用Examples 和ExampleMatchers 将实体实例转换为基础查询。 current official documentation 阐明只有完全匹配可用于非字符串属性。由于您的要求涉及日期字段,因此您只能使用示例查询技术进行精确匹配。

    参考https://stackoverflow.com/a/39555487/4939174

    您也可以参考 this link 了解 Spring Data JPA - 规范和 Querydsl

    【讨论】:

      猜你喜欢
      • 2017-11-29
      • 2018-08-16
      • 2019-04-22
      • 2011-01-27
      • 2020-02-21
      • 2018-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多