我正在使用FilfetDto构建动态查询 如果用户填写了UI中的某个字段,则包含一些值但不是全部。 所以我必须测试每个属性以构建仅在填充(非空)字段上的查询过滤:
JPAQuery dslQuery = new JPAQuery(em);
dslQuery.from(book);
dslQuery.join(book.author, author);
String title = StringUtils.upperCase(StringUtils.trim(_filter.getTitle()));
if (StringUtils.isNotBlank(title)) {
dslQuery.where(book.title.upper().like(title));
}
String isbn = StringUtils.trim(_filter.getIsbn());
if (StringUtils.isNotBlank(isbn)) {
dslQuery.where(book.isbn.like(isbn));
}
if (_filter.getAuthorId() != null) {
dslQuery.where(author.id.eq(_filter.getAuthorId()));
}
有没有办法用另一种更易读的语法来抽象“if”?
我想要像:
JPAQuery dslQuery = new JPAQuery(em);
dslQuery.from(book);
dslQuery.join(book.author, author);
dslQuery.where(book.title.upperIfNotBlank().like(title));
dslQuery.where(book.isbn.likeIfNotNull(isbn));
dslQuery.where(author.id.eqIfNotNull(_filter.getAuthorId()));
如果可以打开“IfNotNull”,甚至是默认行为,那将是很好的...
所以它最终会像这样:
dslQuery.where(book.title.upper().like(title));
dslQuery.where(book.isbn.like(isbn));
dslQuery.where(author.id.eq(_filter.getAuthorId()));
答案 0 :(得分:3)
有没有办法用另一种更易读的语法来抽象“if”?
不,可能不会。 Querydsl表达式的目标是保持与底层持久性技术所使用的形式接近。
如果您想在自己的项目中使用这种方法,请随意将其放入您自己的AbstractJPAQuery子类中。 Querydsl查询旨在针对此类情况进行自定义。
答案 1 :(得分:1)
我创建了一个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);
在实施“过滤器”或“filterByExample”查询时,这非常有用且非常干净/可读。