我使用 JOOQ 查询我的关系数据库,我最近一直在研究连接处理,它让我有点困惑。我试过阅读JavaDoc,还有这个:调用JooQ DSLContext的.close()时,连接何时关闭?但它为我创造了更多的 FUD。
目前我的代码是这样做的:
try (final Connection cn = pool.getConnection()) {
DSLContext dsl = DSL.using(cn, MARIADB);
// query stuff
}
从本质上讲,我将 JOOQ 视为一个根本不进行连接处理的查询器。我从来没有遇到过这段代码的问题。
但是,我确实收到来自IntelliJ的警告,说DSLContext是可自动关闭的,应该由尝试资源处理。我知道在这种情况下不必这样做,但我的第一个问题是"可以吗?用这个替换上面的代码是否安全:
try (final DSLContext dsl = DSL.using(pool.getConnection(), MARIADB)) {
// query stuff
}
另一个 StackOverflow 帖子说,当你使用其中一个辅助方法创建 DSLContext 时,你需要在 DSLContext 上使用 close()。但是,如果您只是传入了连接对象怎么办?close() 还会关闭我的连接吗?
我还发现DSL还有另一个using()允许你分配整个数据源。因此,我也可以这样做:
final DSLContext dsl = DSL.using(pool, MARIADB);
然后完全省略所有尝试资源。这里的权衡是什么?有没有甚至?
IntelliJ进一步抱怨具有AutoClosable接口(继承自Query)的UpdateQuery。是否有必要关闭我的查询?我总是只是调用 execute() 并毫无问题地关闭了底层连接。
我正在寻找的是能够满足这四个要求的代码
- 它使用正确的资源管理
- 它使用JOOQ 在
- IDE 中打开了"尝试使用资源"警告
- 没有警告
上面的各种代码段都至少满足了其中一个要求。但最终连接处理并不重要,因为 JOOQ 中的查询类也会生成大量警告。
最好的方法确实是关闭警告,但对于JOOQ来说,特别是使用Intellij的排除规则。卢卡斯链接的页面上的评论中也提到了如何做到这一点(https://blog.jooq.org/2015/12/02/a-subtle-autocloseable-contract-change-between-java-7-and-java-8/)。
我只需要记住以正确的方式为 JOOQ 课程做事:)
目前我的代码是这样做的:
try (final Connection cn = pool.getConnection()) { DSLContext dsl = DSL.using(cn, MARIADB); // query stuff }
这是正确的用法。
从本质上讲,我将 JOOQ 视为一个根本不进行连接处理的查询器。
这是一个正确的假设。
但是,我确实收到来自IntelliJ的警告,说DSLContext是可自动关闭的,应该由尝试资源处理
。
许多 IDE 都会执行此检查,但通常最好将其关闭。在Java 8+中,你不能合理地期望一个AutoCloseable
真的需要关闭。一个这样的例子是Stream
,它AutoCloseable
那些确实包含资源的情况,但大多数情况下它没有。
这是 Java 8 中一个微妙的 API 更改,导致 IDE 中的此警告最好被关闭(或者您可以指定例外)。
您的问题:
用这个替换上面的代码是否安全:
try (final DSLContext dsl = DSL.using(pool.getConnection(), MARIADB)) { // query stuff }
是的,你可以这样做。DSLContext.close()
调用将仅关闭由DSLContext
创建的资源。在您的情况下,它没有任何影响。
作为记录,创建了足智多谋的DSLContexts,例如通过DSL.using(url, username, password)
然后完全省略所有尝试资源。这里的权衡是什么?有没有甚至?
所有这些都与资源无关。
IntelliJ进一步抱怨具有AutoClosable接口(继承自Query)的UpdateQuery。是否有必要关闭我的查询?我总是只是调用 execute() 并毫无问题地关闭了底层连接。
- 关闭该警告! :-)
- 调用
Query.keepStatement(true)
时,查询可能很足智多谋