使用 JDBCTemplate 流式传输 JDBC 查询结果

2023-11-23

我正在使用 spring java。

我需要返回一个Stream来自数据库查询的对象(我使用ObjectMapper将它们映射到 JSON)。

查询结果可能非常大(超过 500k 个对象),因此我不想将它们存储在内存中。

我已经做到了JpaRepository.

我想知道如何做到这一点JdbcTemplate这样做是否有好处?

即...我们可以使用以下方法优化吞吐量和内存使用吗JdbcTemplate甚至其他图书馆。

我的目标实际上是最终找到运行查询并将所有对象在内存/时间/处理方面打印到输出流的最佳方法。


是的,流会有一个优势,因为它是处理数据的常见抽象,而无需将所有数据都存储在内存中。例如。将流传递给 HTTP 响应。

春季5.3

如果你使用Spring 5.3,有一个方便的方法JdbcTemplate.queryForStream()可以这样使用:

String sql = "select * from table";

Stream<Person > stream = jdbcTemplate.queryForStream(sql, (resultSet, rowNum) -> {
    return new Person(resultSet.getInt(1), resultSet.getString(2));
});

以前的 Spring 版本

旧版本的JDBCTemplate没有直接用于流的功能。但是您可以使用底层数据库连接创建流:

String sql = "select * from table";

Connection connection = jdbcTemplate.getDataSource().getConnection();
PreparedStatement statement = connection.prepareStatement(sql);
ResultSet resultSet = statement.executeQuery();

PersonMapper personMapper = new PersonMapper();

Spliterator<Person> spliterator =
    Spliterators.spliteratorUnknownSize(
        new Iterator<Person>() {
            @Override public boolean hasNext() {
                try {
                    return !resultSet.isAfterLast();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            @Override public Person next() {
                try {
                    if (resultSet.isBeforeFirst()) {
                        resultSet.next();
                    }

                    Person result = new Person(resultSet.getInt(1), resultSet.getString(2));

                    resultSet.next();
                    return result;
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        },
        Spliterator.IMMUTABLE);

Runnable closer = () -> {
    try {
        resultSet.close();
        statement.close();
        connection.close();
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
};

Stream<Person> = StreamSupport.stream(spliterator, false).onClose(closer);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 JDBCTemplate 流式传输 JDBC 查询结果 的相关文章

随机推荐