JOOQ别名构造
JOOQ alias construction
我们使用 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 查询缓存出现问题的原因
或者可能存在另一种方法。
例子
让我们创建 table
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
这是一个错误 (#6025)。生成的 SQL 字符串(以及 Query.equals()
和 Query.hashCode()
行为)应该是 stable,无论您的具体绑定变量如何。
作为一种解决方法,您可以指定一个明确的 table 别名,而不是让 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
我们使用 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 查询缓存出现问题的原因
或者可能存在另一种方法。
例子
让我们创建 table
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
这是一个错误 (#6025)。生成的 SQL 字符串(以及 Query.equals()
和 Query.hashCode()
行为)应该是 stable,无论您的具体绑定变量如何。
作为一种解决方法,您可以指定一个明确的 table 别名,而不是让 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