【问题标题】:Union subselects querydsl联合子选择 querydsl
【发布时间】:2016-05-31 19:52:33
【问题描述】:

我需要优化动态查询。这是一个例子,但它有更多的过滤器(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 中没有得到改进。我是这样做的,因为 Union 不起作用。

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

是否存在通过一次调用 DB 来使用 Querydsl 执行最后一条 sql 的任何方法?

谢谢

【问题讨论】:

    标签: java sql oracle union querydsl


    【解决方案1】:

    com.querydsl.sql.SQLExpressions 中存在一个静态方法 union 来执行此操作。作为参数,使用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());;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多