我将Kotlin与HikariCP和jOOQ一起用于查询数据库。我已经意识到该代码可以按预期工作,然后获取行并随后关闭连接:
class CountriesService(private val datasource: DataSource) {
private val countries = Countries()
fun getCountries(): List<String> {
DSL.using(datasource, SQLDialect.POSTGRES_10)
.use { ctx ->
ctx.select(countries.CO_NAME)
.from(countries)
.orderBy(countries.CO_NAME)
.fetch()
return emptyList()
}
}
}
而如果我使用fetchResultSet()
,则连接永远不会关闭,并且池会变干:
class CountriesService(private val datasource: DataSource) {
private val countries = Countries()
fun getCountries(): List<String> {
DSL.using(datasource, SQLDialect.POSTGRES_10)
.use { ctx ->
ctx.select(countries.CO_NAME)
.from(countries)
.orderBy(countries.CO_NAME)
.fetchResultSet()
return emptyList()
}
}
}
我已经看到AbstractResultQuery#fetchResultSet()
委托给fetchLazy()
方法,所以不确定是否与此有关。
如果我自己获得连接,而不是将其委托给DSLContext
,那么它将起作用:
class CountriesService(private val datasource: DataSource) {
private val countries = Countries()
fun getCountries(): List<String> {
val conn = datasource.connection
conn.use {
DSL.using(it, SQLDialect.POSTGRES_10)
.select(countries.CO_NAME)
.from(countries)
.orderBy(countries.CO_NAME)
.fetchResultSet()
return emptyList()
}
}
}
这是我应该使用的最后一种方法吗?
答案 0 :(得分:0)
它的工作方式与Javadoc中指定的完全相同:
这与调用
fetchLazy().resultSet()
相同,并且将返回包裹着JDBC驱动程序的ResultSet
的{{1}}。关闭此ResultSet可能会关闭生成的ResultSet
或Statement
,具体取决于您对PreparedStatement
的设置。
此方法的要点是您要使用JDBC结果集,而不是让jOOQ为您使用它。因此,您负责资源管理。
给出示例代码,您绝对不应该调用此方法,而应调用keepStatement(boolean)
。例如:
fetch()
注意,您不需要在class CountriesService(private val datasource: DataSource) {
private val countries = Countries()
fun getCountries(): List<String> {
return
DSL.using(datasource, SQLDialect.POSTGRES_10)
.select(countries.CO_NAME)
.from(countries)
.orderBy(countries.CO_NAME)
.fetch(countries.CO_NAME)
}
}
上调用该use()
方法。尽管DSLContext
扩展了DSLContext
,但这仅在您的AutoCloseable
管理基础JDBC连接(即创建它的时候)时才需要。就您而言,当您将数据源传递给DSLContext
时,就不必关闭DSL.using()
。