向从字符串创建的查询添加限制和偏移量

Add limit and offset to query that was created from a String

我有类似字符串的查询

select name from employee

并想用 limit 和 offset 来限制行数。

jOOQ 可以做到这一点吗?我该怎么做?

类似于:

dsl.fetch("select name from employee").limit(10).offset(10);

您可以对字符串查询做的最好的事情是从中创建一个 ResultQuery。它允许您限制底层 java.sql.Statement:

获取的最大行数
create.resultQuery("select name from employee").maxRows(10).fetch();

或者延迟获取然后滚动光标:

create.resultQuery("select name from employee").fetchLazy().fetch(10);

只能使用 SelectQuery 向查询添加偏移量或限制,但我认为在 JOOQ 中没有任何方法可以将字符串查询转换为 SelectQuery

实际上,如果您将 SQL 查询作为字符串存储在数据库中,那么您已经处于非类型安全区域,不妨将 OFFSET x LIMIT y 直接附加到基于字符串的查询.根据您查询的复杂程度,它可能会起作用。

是的,你很接近,但你不能使用 fetch(sql),因为它急切地执行查询并且追加 LIMITOFFSET 为时已晚。我通常不推荐 提供的方法,因为那样的话,您将告诉 RDBMS 更少关于您将要做什么的信息。如果您实际使用 LIMITOFFSET.

,执行计划和资源分配可能会更好

有两种方法可以实现您想要实现的目标:

使用解析器

您可以使用 DSLContext.parser() 来解析您的 SQL 查询,然后修改生成的 SelectQuery,或者从中创建派生的 table。创建派生的 table 可能更简洁:

dsl.selectFrom(dsl.parser().parse("select name from employee"))
   .limit(10)
   .offset(10)
   .fetch();

缺点是解析器必须理解您的 SQL 字符串。一些特定于供应商的功能将不再可用。

优点(从 jOOQ 3.13 开始)是您可以通过这种方式为生成的代码提供附加的转换器和数据类型绑定,因为 jOOQ "know" 列是什么。

使用普通 SQL

您已经在使用普通的 SQL,但使用的方式有误。不要急切地获取数据,只需将查询包装在 DSL.table() 中,然后使用与上述相同的方法。

当使用纯 SQL 时,您必须手动确保生成的 SQL 在句法上是正确的。这包括将您的查询包裹在括号中,并可能为其添加别名,具体取决于您使用的方言:

dsl.selectFrom(table("(select name from employee)").as("t"))
   .limit(10)
   .offset(10)
   .fetch();