如何在JOOQ中设置@Variable

时间:2018-03-31 17:26:02

标签: java jooq

如何使用JOOQ使用@variables? (或者是否有更简单的可能性来显示行号? - 请注意,我需要将所选数据插入到另一个表中,而row_number应始终从0开始!)

SET @row_number = 0;

SELECT 
    (@row_number:=@row_number + 1) AS NUM, FIRST_NAME, LAST_NAME
FROM
    AUTHOR
LIMIT 5;

这就是我认为JOOQ代码看起来像......

Field<Integer> num = DSL.field("@row_number:=@row_number +1", Integer.class);
DSLContext create = DSL.using(connection, dialect);
create.select(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, num)
      .from(AUTHOR)
      .limit(5)
      .fetch();

我需要执行那个

吗?
SET @row_number = 0;

使用普通JDBC

我在StackOverflow上找到了关于变量和JOOQ的内容 - how can we have variable in jooq

编辑:我调查了一下,并读到这个“解决方案”的结果可能会在未来版本中发生变化。我认为将其更改为创建具有pk标识的临时表(从0开始)然后我有相同的结果但没有用户变量设置和更新。

1 个答案:

答案 0 :(得分:2)

正如您所注意到的,jOOQ目前并不严格支持您的语法,因此您必须使用jOOQ API提供的纯SQL模板机制: https://www.jooq.org/doc/latest/manual/sql-building/plain-sql-templating

您已经为查询本身正确地完成了这项工作。现在关于初始化变量,这在理想情况下在同一个JDBC语句中完成,而不是在单独的语句中,以防止jOOQ在连续执行之间关闭JDBC连接(例如,当使用DataSourceConnectionProvider时)引起的副作用。因此,使用jOOQ最直接的方法是使用ExecuteListener将初始化SQL字符串添加到该特定语句,例如。

class InitialisingVariableListener extends DefaultExecuteListener {
    @Override
    public void renderEnd(ExecuteContext ctx) {
        ctx.sql("SET @row_number = 0;" + ctx.sql());
    }
}

在执行查询之前将其挂钩到Configuration

Field<Integer> num = DSL.field("@row_number:=@row_number +1", Integer.class);
DSLContext create = DSL.using(connection, dialect);
create.configuration().set(new InitialisingVariableListener());
create.select(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, num)
      .from(AUTHOR)
      .limit(5)
      .fetch();

如果您在多个查询中重复使用Configuration,您可能希望在其上调用derive()来创建新的Configuration而不是set(),为每个人修改Configuration