我需要优化动态查询。这是一个例子,但它有更多的过滤器(BooleanExpression)
QTable qtable = QTable.table;
BooleanExpression pSubQueryFilter = qtable.field4.in(List<Long>).and((date != null) ? qtable.field5.goe(date) : null);
BooleanExpression pSubQuery =( ((qtable.field1.eq(string1)) .and(qtable .field2.eq(string2)).and(qtable .field3.eq(Boolean.FALSE)))
.or( (qtable.field1.eq(string2)).and(qtable .field2.eq(string1).and(qtable .field3.eq(Boolean.TRUE))))
).and(pSubQueryFilter);
List<T> list = createQuery(pSubQuery ).list(path);
这会生成此选择,但因为OR子句在DB中花费超过30秒。此字段(field1和field2)已在DB中编制索引。
SELECT * FROM table WHERE
(field1= 'string1' AND field2='string2' AND field3=0)
OR (field1= 'string2' AND field2='string1' AND field3=1 )
AND field4 in (1,2,3,4,5,...) AND field5 > =SYSDATE-365
ORDER BY field5 DESC, id DESC
我在SQL中使用此结果将此选择优化为1:
SELECT * FROM table WHERE
id IN ( (SELECT id FROM table WHERE field1= 'string1' AND field2='string2' AND field3=0)
UNION (SELECT id FROM table WHERE field1= 'string2' AND field2='string1' AND field3=1 ) )
AND field4 in (1,2,3,4,5,...) AND field5 > =SYSDATE-365
ORDER BY field5 DESC, id DESC
但在QueryDsl中没有得到改善。我是这样做的,因为联盟不起作用。
BooleanExpression psubq1 = qtable .field1.eq(string1).and(qtable .field2.eq(string2)).and(qtable .field3.eq(Boolean.FALSE));
BooleanExpression psubq2 = qtable .field1.eq(string2).and(qtable .field2.eq(string1)).and(qtable .field3.eq(Boolean.TRUE));
Expression<?>[] args = { qtable .id};
List<Long> resultids = tableRepository.findAllIds(psubq1, args);
resultids.addAll(tableRepository.findAllIds(psubq2, args));
pSubQuery = qtable .id.in(resultids).and(pSubQueryFilter);
用Querydsl进行最后一次sql以及对DB的一次调用是否存在?
谢谢
答案 0 :(得分:0)
union
中存在静态方法com.querydsl.sql.SQLExpressions
来执行此操作。参数使用使用SQLExpressions::select
创建的子查询。
import com.querydsl.core.types.dsl.*;
import com.querydsl.sql.DatePart;
import com.querydsl.sql.SQLExpressions;
import com.querydsl.sql.oracle.OracleGrammar;
import com.querydsl.sql.oracle.OracleQuery;
...
OracleQuery query = new OracleQuery<>(con);
query.select(table).from(table).where(
table.id.in(
SQLExpressions.union(
SQLExpressions.select(table.id).from(table)
.where(table.field1.eq("string1")
.and(table.field2.eq("string2"))
.and(table.field3.eq(Expressions.FALSE))),
SQLExpressions.select(table.id)
.from(table)
.where(table.field1.eq("string2")
.and(table.field2.eq("string1"))
.and(table.field3.eq(Expressions.TRUE))))
)
.and(table.field4.in(1,2,3,4,5))
.and(table.field5.goe(
SQLExpressions.dateadd(DatePart.day, OracleGrammar.sysdate, -365))))
.orderBy(table.field5.desc(), table.id.desc());;