【问题标题】:JOOQ alias constructionJOOQ别名构造
【发布时间】:2017-09-26 11:09:57
【问题描述】:

我们使用 JOOQ 3.7.2,如果 JOOQ 包含不同的绑定参数值,似乎 JOOQ 会为同一个查询计算不同的哈希码,因此如果使用不同的输入执行,查询的部分会有不同的别名

在我们的代码中,我们使用构造asTable,并使用JOOQ构造别名

public final Table<R> asTable() {
    return (new DerivedTable(this)).as("alias_" + Utils.hash(this));
}

从 org.jooq.impl.AbstractQueryPart 计算哈希码

@Override
public int hashCode() {
    // This is a working default implementation. It should be overridden by
    // concrete subclasses, to improve performance

    return create().renderInlined(this).hashCode();
}

renderInlined(this) 对于具有不同输入值的相同查询是不同的。例如

where rownum = 1
    order by MYFIELD asc
  ) alias_132316169
) alias_55254251

where rownum = 2
    order by MYFIELD asc
  ) alias_117501160
) alias_82323306

检查rownum相等的值是绑定变量

是否可以为使用绑定变量的查询生成相同的别名代码?因为现在 JOOQ 生成了不同的别名,这是导致 Oracle 查询缓存问题的原因

或者可能存在其他方法。

示例

让我们创建表

create table JOOQ_TEST (id number, val varchar2(100))

然后运行下一个代码

@Test
public void testSelect() throws Exception {
    List<Long> ids = new ArrayList<Long>();
    ids.add(1L);
    ids.add(2L);

    for (Long i : ids) {
        Table table = dsl.select(JOOQ_TEST.VAL, JOOQ_TEST.ID)
                .from(JOOQ_TEST)
                .where(JOOQ_TEST.ID.eq(i))
                .orderBy(JOOQ_TEST.ID).asTable();

        dsl.select().from(table).fetch();
    }
}

我们得到了

2017-04-28 17:37:58,235 DEBUG [main] org.jooq.tools.LoggerListener Executing query          : 
select 
  alias_116981037.VAL, 
  alias_116981037.ID
from (
  select 
    JOOQ_TEST.VAL, 
    JOOQ_TEST.ID
  from JOOQ_TEST
  where JOOQ_TEST.ID = ?
  order by JOOQ_TEST.ID asc
) alias_116981037
2017-04-28 17:37:58,236 DEBUG [main] org.jooq.tools.LoggerListener -> with bind values      : 
select 
  alias_116981037.VAL, 
  alias_116981037.ID
from (
  select 
    JOOQ_TEST.VAL, 
    JOOQ_TEST.ID
  from JOOQ_TEST
  where JOOQ_TEST.ID = 1
  order by JOOQ_TEST.ID asc
) alias_116981037
2017-04-28 17:37:58,593 DEBUG [main] org.jooq.tools.StopWatch Query executed           : Total: 361.112ms
2017-04-28 17:37:58,613 DEBUG [main] org.jooq.tools.LoggerListener Fetched result           : +----+----+
2017-04-28 17:37:58,613 DEBUG [main] org.jooq.tools.LoggerListener                          : |VAL |  ID|
2017-04-28 17:37:58,613 DEBUG [main] org.jooq.tools.LoggerListener                          : +----+----+
2017-04-28 17:37:58,613 DEBUG [main] org.jooq.tools.StopWatch Finishing                : Total: 381.65ms, +20.538ms
2017-04-28 17:37:58,614 DEBUG [main] org.jooq.tools.LoggerListener Executing query          : 
select 
  alias_4853230.VAL, 
  alias_4853230.ID
from (
  select 
    JOOQ_TEST.VAL, 
    JOOQ_TEST.ID
  from JOOQ_TEST
  where JOOQ_TEST.ID = ?
  order by JOOQ_TEST.ID asc
) alias_4853230
2017-04-28 17:37:58,615 DEBUG [main] org.jooq.tools.LoggerListener -> with bind values      : 
select 
  alias_4853230.VAL, 
  alias_4853230.ID
from (
  select 
    JOOQ_TEST.VAL, 
    JOOQ_TEST.ID
  from JOOQ_TEST
  where JOOQ_TEST.ID = 2
  order by JOOQ_TEST.ID asc
) alias_4853230
2017-04-28 17:37:58,633 DEBUG [main] org.jooq.tools.StopWatch Query executed           : Total: 18.899ms
2017-04-28 17:37:58,637 DEBUG [main] org.jooq.tools.LoggerListener Fetched result           : +----+----+
2017-04-28 17:37:58,638 DEBUG [main] org.jooq.tools.LoggerListener                          : |VAL |  ID|
2017-04-28 17:37:58,638 DEBUG [main] org.jooq.tools.LoggerListener                          : +----+----+
2017-04-28 17:37:58,638 DEBUG [main] org.jooq.tools.StopWatch Finishing                : Total: 23.931ms, +5.031ms

【问题讨论】:

  • JOOQ哈希码和Oracle查询缓存有什么关系? Oracle 如何查看哈希码?它会以某种方式成为查询字符串的一部分吗?
  • 是的,它为别名.as("alias_" + Utils.hash(this)) 生成值,并且别名成为查询的一部分
  • 您能否为该派生表手动分配不同的(稳定且有意义的)别名?有一种方法asTable("betterAlias")我相信。
  • 我可以,但可能有办法正确配置它
  • 是的,我刚加的,可能有点人为,但是别名不一样

标签: java jooq


【解决方案1】:

这是一个错误 (#6025)。无论您的具体绑定变量如何,生成的 SQL 字符串(以及 Query.equals()Query.hashCode() 行为)都应该是稳定的。

作为一种解决方法,您可以指定一个明确的表别名,而不是让 jOOQ 为您生成一个:

Table table = dsl.select(JOOQ_TEST.VAL, JOOQ_TEST.ID)
                 .from(JOOQ_TEST)
                 .where(JOOQ_TEST.ID.eq(i))
                 .orderBy(JOOQ_TEST.ID).asTable("t"); // table alias here

【讨论】:

    猜你喜欢
    • 2017-11-23
    • 2022-01-22
    • 1970-01-01
    • 2014-11-05
    • 2020-12-31
    • 2014-11-16
    • 2021-07-29
    • 1970-01-01
    • 2012-08-05
    相关资源
    最近更新 更多