具有可选参数的JPA / Hibernate自定义查询

时间:2017-11-14 13:39:09

标签: java jpa

我有一个实体

@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字符串构建,但这不是一个好方法。

2 个答案:

答案 0 :(得分:0)

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

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

所以你的代码将是那样的

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()]));

答案 1 :(得分:0)

Spring Data JPA按示例查询技术使用ExampleExampleMatcher将实体实例转换为基础查询。 current official documentation说明只有非字符串属性才能使用完全匹配。由于您的要求涉及日期字段,因此您只能与逐个查询技术完全匹配。

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

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