【问题标题】:Dynamic SQL Projection with multiple joins in QueryDSLQueryDSL 中具有多个连接的动态 SQL 投影
【发布时间】:2021-08-27 16:12:25
【问题描述】:

我正在尝试使用连接 2 个表进行动态 sql 投影。这里 visibleColumns 是逗号分隔的字符串(我想在 SQL 选择语句中显示的动态列)。

QActive qActive = QActive.active;.
QCustomer qCustomer = QCustomer.customer;
QBaseCounterParty qBaseCounterParty = QBaseCounterParty.baseCounterParty;

StringExpression path = Expressions.stringPath(qActive, visibleColumns);

return JPQLQuery<String> resultSet = query.select(path).from(qActive).innerJoin(qActive.customer, qCustomer).on(qInvoice.customer.id.eq(qCustomer.id))
            .innerJoin(qBaseCounterParty).on(qCustomer.id.eq(qBaseCounterParty.id)).where(queryDslSpec).orderBy(sort)
            .offset(request.getPagination().getStartRow()).limit(request.getPagination().getRowsPerPage());

所以每当我尝试运行它时,它都会使用 400 Bad Request 创建如下查询:

select active.docNumber, customerName from Active active inner join Customer customer with active.id = customer.id inner join BaseCounterParty baseCounterParty with customer.id = baseCounterParty.id order by active.transactionDate desc

我不确定如何从其他表中选择列,因为列完全是动态的。

【问题讨论】:

  • 您无法从字符串中获取列。这不是 QueryDSL 的工作方式。您必须将列与 Q 类型匹配,并将这些 Qtypes 的数组传递给 SELECT。
  • @GuillaumeF。你能告诉我如何用代码做到这一点。
  • @GuillaumeF。我需要选择动态列,但不确定如何匹配 Qtype 中的列,因为它是动态的,所以我不知道哪个列可以出现。
  • .select(qCustomer.name, qBaseCounterParty.whatever, ...)。 fetch 会返回一个 Tuple 对象,然后你可以做tuple.get(qCustomer.name)
  • @GuillaumeF。在 select 语句中,我不知道 UI 将发送哪些列,而 UI 实际上发送了一个列列表,所以我如何选择并且表之间也存在连接,所以不知道哪一列来自哪个表以便获取该列的 QType 很难

标签: java spring spring-data-jpa querydsl


【解决方案1】:

这里有一些使用 QueryDSL 构造函数投影的例子,可以用任何 dto 填充数据。 警告 dto 构造函数必须具有相同的参数类型等。

QActive qActive = QActive.active;.
QCustomer qCustomer = QCustomer.customer;
QBaseCounterParty qBaseCounterParty = QBaseCounterParty.baseCounterParty;

return JPQLQuery<SomeDTO> resultSet =  query.select(Projections.constructor(SomeDTO.class, 
                    qActive.someValue1,
                    qBaseCounterParty.someValue2,
                    qActive.someValue3))
        .from(qActive)
        .innerJoin(qActive.customer, qCustomer).on(qInvoice.customer.id.eq(qCustomer.id))
        .innerJoin(qBaseCounterParty).on(qCustomer.id.eq(qBaseCounterParty.id))
        .where(queryDslSpec)
        .orderBy(sort)
        .offset(request.getPagination().getStartRow()).limit(request.getPagination().getRowsPerPage());

public class SomeDTO {

// QueryDSL Constructor
public SomeDTO(String value1, int value2, String value3) {
    this.value1 = value1;
    this.value2 = value2;
    this.value3 = value3;
}

}

【讨论】:

  • 在 query.select() 中,您正在传递您知道的列。我的问题是我需要选择动态投影,那么我该如何选择动态投影。
  • @Deepak 好的。让我们尝试使用 json 映射。所以你可以存储任何东西并根据需要获取它(字符串或地图等)。
猜你喜欢
  • 2018-11-05
  • 2015-02-26
  • 2020-07-05
  • 2013-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-22
  • 1970-01-01
相关资源
最近更新 更多