假设我有CustomerQueryInfo
bean,其中包含以下属性:
我想使用此类型的对象执行“ QueryDSL ”搜索,该对象将返回客户列表List<Customer>
。
如果CustomerQueryInfo
的某个字段是null
,我不想在搜索中使用它。因此,将所有三个字段设置为CustomerQueryInfo
的null
对象将返回所有客户。
我正在寻找使用QueryDSL执行此类搜索的最佳做法。
是这样的:
private BooleanExpression isFirstNameLike(String firstName){
if(firstName==null)
return true BooleanExpression somehow;
return QCustomer.customer.firstName.like(firstName);
}
private BooleanExpression isStatutEq(StatusEnum status){
if(status==null)
return true BooleanExpression somehow;
return QCustomer.customer.status.eq(status);
}
然后:
return query.from(customer).where(isFirstNameLike(customerQueryInfo.getFirstName).and(isLastNameLike(customerQueryInfo.getLastName).and(isStatusEq(customerQueryInfo.getStatus))).list;
BooleanExpression
?答案 0 :(得分:18)
如何返回计算结果为true的BooleanExpression?
BooleanExpression alwaysTrue = Expressions.asBoolean(true).isTrue();
答案 1 :(得分:17)
您可以安全地使用像这样的空谓词
private BooleanExpression isFirstNameLike(String firstName){
return firstName != null ? customer.firstName.like(firstName) : null;
}
private BooleanExpression isStatusEq(StatusEnum status){
return status != null ? customer.status.eq(status) : null;
}
并使用其中的varargs方面
query.from(customer)
.where(
isFirstNameLike(customerQueryInfo.getFirstName()),
isLastNameLike(customerQueryInfo.getLastName()),
isStatusEq(customerQueryInfo.getStatus()))
.list(customer);
答案 2 :(得分:7)
使用java 8和BooleanBuilder,您可以实现这样的优雅方式:
Java 8 Optional&amp; LAMBDA
public final class ProductQuery {
public static BooleanExpression nameEqualTo(String name){
return ofNullable(name).map(QProduct.product.name::eq).orElse(null);
}
}
BooleanBuilder
BooleanBuilder where = new BooleanBuilder()
.and(ProductQuery.nameEqualTo(name));
答案 3 :(得分:5)
我创建了一个QueryDSLHelper类,它具有静态方法,在添加表达式之前进行空值检查。像这样:
public static void goe(BooleanBuilder builder, DateTimePath<Date> path, Date value) {
if(date!=null) {
builder.and(path.goe(value));
}
}
public static void like(BooleanBuilder builder, StringPath path, String value) {
if(value!=null) {
builder.and(path.like(value));
}
}
现在我可以静态导入这些方法并在一行上调用它们:
like(builder, book.isbn, isbn);
这在实施“过滤器”时非常有用且非常干净/可读。或者&#39; filterByExample&#39;查询。
虽然Timo的上述答案可能是更好的解决方案。
答案 4 :(得分:0)
您可以执行以下操作:
private BooleanExpression isFirstNameLike(String firstName){
final QCustomer customer = QCustomer.customer;
return customer.firstName.isNull().or(customer.firstName.like(firstName));
}
private BooleanExpression isStatutEq(StatusEnum status){
final QCustomer customer = QCustomer.customer;
return customer.status.isNull().or(customer.status.eq(status));
}
或者,如果您想真正匹配firstName
和/或状态,请更改
.isNull().or(...) to isNotNull().and(...)