[英]Build a dynamic query with Hibernate (no Criteria API)
我有以下方法:
public List<Parcel> filter(ParcelFilterParameters pfp) {
try (var session = sessionFactory.getCurrentSession()) {
var baseQuery = "from Parcel ";
var filters = new ArrayList<String>();
pfp.getCustomerId().ifPresent(e -> filters.add(" owner.id = :ownerId "));
pfp.getCategoryId().ifPresent(e -> filters.add(" category.id = :categoryId "));
if (!filters.isEmpty()) {
baseQuery = baseQuery + " where " + String.join(" and ", filters);
}
Query<Parcel> query = session.createQuery(baseQuery, Parcel.class);
pfp.getCustomerId().ifPresent(e -> query.setParameter("ownerId", e));
pfp.getCategoryId().ifPresent(e -> query.setParameter("categoryId", e));
return query.list();
}
}
这是 ParcelFilterParameters class:
public class ParcelFilterParameters {
private Optional<Integer> customerId;
private Optional<Integer> categoryId;
// getters and setters...
}
虽然看起来很奇怪,但它确实有效,但这对其他一些实体重复,所以我想知道我是否可以以某种方式使其更通用(不使用 Criteria API)? 或者至少跳过第二批ifPresent(e ->...
s?
尽管您没有要求使用 Criteria API ,但请考虑使用org.hibernate.criterion.Example
。 它可以很好地适应越来越多的实体。 该示例自省每个不是 null 的字段,并将从中构建您的where
-block。
首先在ParcelFilterParameters
中,我们应该从字段中删除Optioals
,因为Example
可以很好地处理空值。 然后我们从ParcelFilterParameters
构建一个Parcel
对象并从中创建一个Example
。 Example
可以作为Criterion
添加到查询中。
public List<Parcel> filter(ParcelFilterParameters pfp) {
try (var session = sessionFactory.getCurrentSession()) {
// Build example Parcel from ParcelFilterParameters
Parcel parcel = new Parcel();
// initialize customer/owner and category ...
parcel.getOwner().setId(pfp.getCustomerId());
parcel.getCategory().setId(pfp.getCategoryId());
return session.createCriteria(Parcel.class)
.add(Example.create(parcel))
.list();
}
}
为了避免the second batch of ifPresent
你可以使用 map 来保存所有查询参数:
List<String> filters = new ArrayList<>();
Map<String, Object> params = new HashMap<>();
pfp.getCustomerId().ifPresent(e -> {
filters.add(" owner.id = :ownerId ");
params.put("ownerId", e);
});
pfp.getCategoryId().ifPresent(e -> {
filters.add(" category.id = :categoryId ");
params.put("categoryId", e);
});
并在单个方法调用中应用它们:
Query<Parcel> query = session.createQuery(baseQuery, Parcel.class);
query.setProperties(params);
return query.list();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.