【问题标题】:QueryDSL join with limit 1QueryDSL 加入限制为 1
【发布时间】:2018-04-03 17:16:42
【问题描述】:

我有两张这样的表:

+------------------+              +------------------+                                                                                                                                 
|     CHANGESET    | 1         N  |     DECISION     |                                                                                                                                 
|                  |--------------|                  |                                                                                                                                 
|                  |              |                  |                                                                                                                                 
+------------------+              +------------------+                                                                                                                                 

我需要根据某些条件获取 CHANGESET 记录列表并仅加入一条 DECISION 记录,最后一条基于 dateTimeStamp。

所以,我有一个这样的查询:

SELECT * FROM CHANGESET ch
  LEFT JOIN (
    SELECT * FROM
      (
        SELECT * FROM CHANGESETDECISION
        ORDER BY DECISIONTIMESTAMP DESC
      )
    WHERE ROWNUM = 1
    ) chd
      ON chd.CHANGESETID = ch.ID
  WHERE ch.CHANGESETSTATUSID IN ('DRAFT','APPROVED')
          -- AND some other criteria...
ORDER BY ch.ID;

或者我可以通过以下查询得到相同的结果:

SELECT * FROM
  (
    SELECT
      RANK()
      OVER (
        PARTITION BY CH.ID
        ORDER BY CHD.DECISIONTIMESTAMP ) rnk,
      ch.*,
      chd.DECISIONTIMESTAMP,
      chd.CHANGESETID
    FROM CHANGESET ch
      LEFT JOIN CHANGESETDECISION chd ON chd.CHANGESETID = ch.ID
  ) WHERE rnk = 1;

我需要的是用 QueryDSL 编写它。我试过这样的事情:

    private SQLQuery getLastApproved() {
        return createQuery()
            .from(CHANGESETDECISION)
            .limit(1)
            .orderBy(new OrderSpecifier<>(Order.DESC, CHANGESETDECISION.decisiontimestamp))
            .where(CHANGESETDECISION.approved.eq(COMMON_YES_VALUE));
    }

并将其加入:

createQuery()
            .from(CHANGESET)
            .leftJoin(getLastApproved())
            .where(CHANGESETDECISION.decisiontimestamp.isNull().or(CHANGESETDECISION.decisiontimestamp.eq(getTimestamp())))
            .list();

但它根本不起作用,因为SQLQuerySQLSubQuery 不是基于EntityPath&lt;?&gt;

您对如何实现它有什么建议吗?

在项目中,我们使用的是 QueryDSL 3.6.9。

【问题讨论】:

    标签: querydsl


    【解决方案1】:

    更新为使用 querydsl 3.6.9

    使用leftJoin方法public Q leftJoin(SubQueryExpression&lt;?&gt; target, Path&lt;?&gt; alias),使用querydsl 3.6.9的示例。

    PathBuilder<String> alias = new PathBuilder<>(String.class, "alias");
    query.from(dual)
            .leftJoin(new SQLSubQuery()
                    .from(dual)
                    .list(dual.dummy), alias)
            .on(alias.get(dual.dummy).eq(dual.dummy));
    

    【讨论】:

    • 在 3.6.9 中没有以 query 作为第一个参数,别名作为第二个参数的 leftJoin。 LeftJoin 仅采用 (EntityPath target) 或 (RelationalFuncitionCall target, Path alias) 或 (SubQueryExpression target, Path alias) 或 (ForeignKey key, entity)。
    • 更新为使用 querydsl 3.6.9。
    猜你喜欢
    • 1970-01-01
    • 2013-05-03
    • 1970-01-01
    • 2014-11-12
    • 2012-08-06
    • 2018-03-15
    • 2021-07-15
    • 2018-01-29
    • 1970-01-01
    相关资源
    最近更新 更多