无法在 Kotlin/Java 中使用 jooq DSL 执行 where 子句
cannot do a where clause with jooq DSL in Kotlin/Java
我正在尝试 运行 使用 Kotlin 中的 jooq 进行以下形式的查询:
val create = DSL.using(SQLDialect.POSTGRES)
val query: Query = create.select().from(DSL.table(tableName))
.where(DSL.field("timestamp").between("1970-01-01T00:00:00Z").and("2021-11-05T00:00:00Z"))
.orderBy(DSL.field("id").desc())
上面的代码给我:
syntax error at or near \"and\
此外,在调试器中查看此查询,query.sql
呈现为:
select * from data_table where timestamp between ? and ? order by id desc
我不确定 ?
是否表示它无法将值呈现为 SQL 或者它们是某种占位符..
此外,代码在没有 where
链的情况下也能正常工作。
此外,在 Postgres 命令行上,我可以 运行 以下内容并执行查询:
select * from data_table where timestamp between '1970-01-01T00:00:00Z' and '2021-11-05T00:00:00Z' order by id
查询架构上的数据类型,timestamp
列类型呈现为 timestamp without time zone
。
在我声明变量之前:
val lowFilter = "1970-01-01T00:00:00Z"
val highFilter = "2021-11-05T00:00:00Z"
这不起作用,似乎传递原始字符串也不起作用。我对此很陌生,所以我很确定我搞砸了这里的用法。
编辑
按照@nulldroid 的建议,做了类似的事情:
.where(DSL.field("starttime").between(DSL.timestamp("1970-01-01T00:00:00Z")).and(DSL.timestamp("2021-11-05T00:00:00Z")))
这导致:
Type class org.jooq.impl.Val is not supported in dialect POSTGRES"
未使用代码生成器:
我假设您有充分的理由不对这个特定查询使用 code generator,主要原因通常是您的架构是动态的。
因此,编写查询的正确方法是:
create.select()
.from(DSL.table(tableName))
// Attach a DataType to your timestamp field, to let jOOQ know about this
.where(DSL.field("timestamp", SQLDataType.OFFSETDATETIME)
// Use bind values of a temporal type
.between(OffsetDateTime.parse("1970-01-01T00:00:00Z"))
.and(OffsetDateTime.parse("2021-11-05T00:00:00Z")))
.orderBy(DSL.field("id").desc())
请注意我是如何使用实际时间数据类型而不是字符串来比较日期和声明字段的。
根据您问题的 UTC 时间戳,我假设您正在使用 TIMESTAMPTZ
。否则,如果您使用 TIMESTAMP
,只需将 OffsetDateTime
替换为 LocalDateTime
...
使用代码生成器
如果使用代码生成器,如果您的架构不是动态的,总是推荐,您将编写与上面几乎相同的内容,但类型安全:
create.select()
.from(MY_TABLE)
// Attach a DataType to your timestamp field, to let jOOQ know about this
.where(MY_TABLE.TIMESTAMP
// Use bind values of a temporal type
.between(OffsetDateTime.parse("1970-01-01T00:00:00Z"))
.and(OffsetDateTime.parse("2021-11-05T00:00:00Z")))
.orderBy(MY_TABLE.ID.desc())
我正在尝试 运行 使用 Kotlin 中的 jooq 进行以下形式的查询:
val create = DSL.using(SQLDialect.POSTGRES)
val query: Query = create.select().from(DSL.table(tableName))
.where(DSL.field("timestamp").between("1970-01-01T00:00:00Z").and("2021-11-05T00:00:00Z"))
.orderBy(DSL.field("id").desc())
上面的代码给我:
syntax error at or near \"and\
此外,在调试器中查看此查询,query.sql
呈现为:
select * from data_table where timestamp between ? and ? order by id desc
我不确定 ?
是否表示它无法将值呈现为 SQL 或者它们是某种占位符..
此外,代码在没有 where
链的情况下也能正常工作。
此外,在 Postgres 命令行上,我可以 运行 以下内容并执行查询:
select * from data_table where timestamp between '1970-01-01T00:00:00Z' and '2021-11-05T00:00:00Z' order by id
查询架构上的数据类型,timestamp
列类型呈现为 timestamp without time zone
。
在我声明变量之前:
val lowFilter = "1970-01-01T00:00:00Z"
val highFilter = "2021-11-05T00:00:00Z"
这不起作用,似乎传递原始字符串也不起作用。我对此很陌生,所以我很确定我搞砸了这里的用法。
编辑 按照@nulldroid 的建议,做了类似的事情:
.where(DSL.field("starttime").between(DSL.timestamp("1970-01-01T00:00:00Z")).and(DSL.timestamp("2021-11-05T00:00:00Z")))
这导致:
Type class org.jooq.impl.Val is not supported in dialect POSTGRES"
未使用代码生成器:
我假设您有充分的理由不对这个特定查询使用 code generator,主要原因通常是您的架构是动态的。
因此,编写查询的正确方法是:
create.select()
.from(DSL.table(tableName))
// Attach a DataType to your timestamp field, to let jOOQ know about this
.where(DSL.field("timestamp", SQLDataType.OFFSETDATETIME)
// Use bind values of a temporal type
.between(OffsetDateTime.parse("1970-01-01T00:00:00Z"))
.and(OffsetDateTime.parse("2021-11-05T00:00:00Z")))
.orderBy(DSL.field("id").desc())
请注意我是如何使用实际时间数据类型而不是字符串来比较日期和声明字段的。
根据您问题的 UTC 时间戳,我假设您正在使用 TIMESTAMPTZ
。否则,如果您使用 TIMESTAMP
,只需将 OffsetDateTime
替换为 LocalDateTime
...
使用代码生成器
如果使用代码生成器,如果您的架构不是动态的,总是推荐,您将编写与上面几乎相同的内容,但类型安全:
create.select()
.from(MY_TABLE)
// Attach a DataType to your timestamp field, to let jOOQ know about this
.where(MY_TABLE.TIMESTAMP
// Use bind values of a temporal type
.between(OffsetDateTime.parse("1970-01-01T00:00:00Z"))
.and(OffsetDateTime.parse("2021-11-05T00:00:00Z")))
.orderBy(MY_TABLE.ID.desc())