批量连接
适用于 ✅ 开源版 ✅ 专业版 ✅ 企业版
jOOQ 支持通过专用 API 进行 JDBC 批量处理,以显式地批量处理某些语句,从而提高性能。 如果性能在应用程序的某些领域中是“事后诸葛亮”,或者批量处理在所有环境中效果不佳(甚至会使情况更糟,具体取决于方言),则可以使用 org.jooq.tools.jdbc.BatchedConnection
来透明地缓冲所有 jOOQ(和其他 JDBC)语句,并将其作为批处理延迟执行。
假设您可能有两个服务,它们在后台生成以下 INSERT
语句
// "Regular code": // --------------- module1.insertSomething(configuration); module2.insertSomethingElse(configuration); // The above might generate... (each line is a statement) // INSERT INTO something (A, B) VALUES (?, ?) // INSERT INTO something (A, B) VALUES (?, ?) // INSERT INTO something (A, B) VALUES (?, ?) // INSERT INTO something (A, B, C) VALUES (?, ?, ?) // INSERT INTO something (A, B, C) VALUES (?, ?, ?) // INSERT INTO something (A, B) VALUES (?, ?) // INSERT INTO something_else (X, Y) VALUES (?, ?) // INSERT INTO something_else (X, Y) VALUES (?, ?) // INSERT INTO something_else (X, Y) VALUES (?, ?)
业务逻辑很复杂,您不想再次修改它,只是为了提高性能。 您现在可以将您自己的 JDBC 连接包装在 org.jooq.tools.jdbc.BatchedConnection
中,或者通过调用 DSLContext.batched()
让 jOOQ 为您执行此操作
// "Batch-collecting code". // Alternatively, use DSLContext.batchedResult() to return a result from the lambda. DSL.using(configuration).batched(c -> { module1.insertSomething(c); module2.insertSomethingElse(c); }); // The above might now generate... (each line is a batch statement) // INSERT INTO something (A, B) VALUES (?, ?) -- With 3 calls to PreparedStatement.addBatch() // INSERT INTO something (A, B, C) VALUES (?, ?, ?) -- With 2 calls to PreparedStatement.addBatch() // INSERT INTO something (A, B) VALUES (?, ?) -- With 1 calls to PreparedStatement.addBatch() // INSERT INTO something_else (X, Y) VALUES (?, ?) -- With 2 calls to PreparedStatement.addBatch()
无需更改 SQL 字符串或执行顺序,通过这种方式,现在可以缓冲连续相同的 SQL 字符串,并在单个批处理中收集它们的绑定值。
一旦发生以下任何事件,缓冲的批处理就会被执行,并创建一个新批处理
- SQL 字符串发生更改(包括“无关”的空格更改)。
- 执行生成结果的查询。
- 创建 静态语句(而不是预处理语句)。
- 连接已关闭,或事务已提交,或调用了与 JDBC 的任何其他此类交互。
- 达到 批处理大小 阈值。
限制
虽然这种批处理方法对大多数用例都是透明的,但存在一些限制
- 由于查询执行被延迟,JDBC
PreparedStatement#executeUpdate()
调用还不能生成正确的行计数。 它们总是生成0
,相反,因为没有(尚未)受到影响的行。 - 如果查询产生结果(例如,普通的 SELECT 语句,或 INSERT .. RETURNING 语句),则会阻止批处理。
要跟踪有效批处理的语句,请打开 DEBUG 日志记录。
有关此功能的更多已知限制,请参阅 #10692。
反馈
您对此页面有任何反馈吗? 我们很乐意听取您的意见!