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

问题描述 投票:1回答:1

我正在使用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()
        }
    }
}

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

kotlin jooq hikaricp
1个回答
0
投票

它完全按照Javadoc中的规定工作:

这与调用fetchLazy().resultSet()相同,并将返回包含JDBC驱动程序的ResultSetResultSet。关闭此ResultSet可能会关闭生成的StatementPreparedStatement,具体取决于您对keepStatement(boolean)的设置。

这个方法的要点是你想要使用JDBC结果集而不是让jOOQ为你消耗它。所以,你负责资源管理。

鉴于您的示例代码,您绝对不应该调用此方法,而是调用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,但只有当你的DSLContext管理底层JDBC连接时(即它创建它时),才需要这样做。在您的情况下,当您将数据源传递给DSL.using()时,您不必关闭DSLContext

© www.soinside.com 2019 - 2024. All rights reserved.