【问题标题】:Creating a PreparedStatement from a jooq Query从 jooq 查询创建 PreparedStatement
【发布时间】:2014-12-21 20:45:25
【问题描述】:

目前正在探索JOOQ的可能性,我想慎重入手,只使用JOOQ作为SQL builder。我将我的数据库模式定义为从CustomTable 派生的类,以获得类型安全。 这导致代码像

Param<Integer> pId = ...
Query query = context.select(sometable.somefield.max())
                     .from(sometable)
                     .where(sometable.id.eq(pId)
                     ;

其中sometable 是一个变量,用于保存我的一个表实例。

我目前对query 所做的类似于

PreparedStatement pstmt = connection.prepareStatement(query.getSQL());
pstmt.setObject(1, pId.getValue(), pId.getDataType().getSQLType());

但是一旦语句有更多参数,我就开始对 JOOQ 的实现与setObjects 的第一个参数产生复杂的依赖关系。

我想使用query.getBindValues(),但这只会返回要绑定到语句的普通 Java 对象。我必须假设订单与setObject 的仓位订单匹配,此外我现在错过了getSQLType()。所以这也不是什么好办法。

然后我希望找到类似query.getPreparedStatement(connection) 的东西来从提供的连接创建语句,并很好地填写了所有参数,但这似乎不存在。

是否有一些巧妙的方法可以从我丢失的 JOOQ Query 中获取 PreparedStatement

【问题讨论】:

  • 为了完整起见,您能否添加一个简短的解释说明您为什么不想使用 jOOQ 来执行查询?
  • 我还没有准备好将我的灵魂完全卖给 JOOQ :-) 最重要的是,我读到 JOOQ 最初是一个 SQL 构建器,我认为三个职责自然分离:1 ) 获取正确的查询或语句,2) 使用池、连接、语句等处理与数据库的连接,3) 从查询结果中读取数据。通过使用 PreparedStatement 来交换 Connection 和 JOOQ Query 可以很好地分离 (1) 和 (2)。
  • 你的灵魂可以奔跑,但它无法隐藏。 jOOQ 已经准备语句 5 年了 - 大公司在生产中使用...不知道你在担心什么:) 从一开始,jOOQ 就将变量绑定到 PreparedStatement。 SQL 提取功能是后来才出现的。无论如何,我会给出答案

标签: prepared-statement jooq sqlbuilder


【解决方案1】:

默认情况下,每次运行 Query.execute() 或任何各种 ResultQuery.fetch() 方法时,jOOQ 都会在内部创建 PreparedStatements。我认为允许用户准备语句并通过新方法Query.statement() 访问此类未执行的语句可能是一个好主意。我已将此添加为功能请求:

今天,您可以使用您提到的 API 自己提取 SQL 和绑定变量,或多或少采用您描述的方式(注意,还有 Query.getParams()),它以绑定顺序返回 Param 类型.

但是,请注意,通常没有任何充分的理由(除了在吞吐量非常高的情况下的 SQL 字符串缓存)来提取 SQL 字符串并直接通过 JDBC 自己执行它。 jOOQ主要用于渲染SQL来执行它。

【讨论】:

  • 感谢您将此作为功能请求。如果我有发言权,我会更喜欢ResultQuery.statement(Connection con),因为只有这样我才能继续拥有连接,只将它借给 JOOQ 用于创建语句。
  • @Harald:虽然对于给定的用例,您可能更喜欢特定的 API,但在 jOOQ API 的整体上下文中会非常令人惊讶。在任何可比较的方法中几乎都没有提及Connection,因此在此处添加它是没有意义的。本质上,会有ResultQuery.statement(),也许还有DSLContext.statement(ResultQuery)。这两种方法都将与现有的ResultQuery.keepStatement() 行为一致。我希望这是有道理的?
  • 我不确定是否应该添加方法调用,因为我会用这个语句做什么?它来自我在通话地点并不真正拥有的联系,我想知道对这个声明做任何事情是否明智。但我承认,我对 JDBC 的了解还不够深入。
  • 这确实是一个边缘案例,但在 jOOQ 中已经有可能访问 JDBC ResultSet,因此访问 PreparedStatement 也就不足为奇了。一个用例是手动批处理,或者每次使用新的绑定值连续执行缓存语句......好吧,边缘情况:-)
猜你喜欢
  • 2012-12-12
  • 2011-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 2014-11-27
相关资源
最近更新 更多