jOOQ получить против fetchResultSet и закрыть соединение в Kotlin - PullRequest
1 голос
/ 25 марта 2019

Я использую 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 голосов
/ 25 марта 2019

Он работает точно так, как указано в Javadoc :

Это то же самое, что и вызов fetchLazy().resultSet(), и он возвращает ResultSet, упаковывающий ResultSet драйвера JDBC,Закрытие этого ResultSet может привести к закрытию производящего Statement или PreparedStatement, в зависимости от настроек 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.

...