jOOQ fetch vs fetchResultSet并在Kotlin中关闭连接

时间:2019-03-25 08:51:36

标签: kotlin jooq hikaricp

我将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()
        }
    }
}

这是我应该使用的最后一种方法吗?

1 个答案:

答案 0 :(得分:0)

它的工作方式与Javadoc中指定的完全相同:

  

这与调用fetchLazy().resultSet()相同,并且将返回包裹着JDBC驱动程序的ResultSet的{​​{1}}。关闭此ResultSet可能会关闭生成的ResultSetStatement,具体取决于您对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()