Spring
JDBCTemplate을 사용한 JDBC 쿼리의 스트림 결과
기록만이살길
2022. 11. 13. 19:38
JDBCTemplate을 사용한 JDBC 쿼리의 스트림 결과
1. 질문(문제점):
나는 Spring 자바를 사용하고 있습니다.
Stream데이터베이스 쿼리에서 개체 를 반환해야 합니다 ( ObjectMapper이를 JSON에 매핑하는 데 사용).
쿼리 결과는 상당히 클 수 있으므로(500k 개체 이상) 메모리에 저장하고 싶지 않습니다.
나는 그것을 했다 JpaRepository.
어떻게 할 수 있고 그렇게 할 JdbcTemplate때 이점이 있는지 알고 싶습니다.
JdbcTemplate즉 ... 또는 다른 라이브러리 를 사용하여 처리량과 메모리 사용을 최적화할 수 있습니까?
내 목표는 결국 메모리/시간/처리 측면에서 쿼리를 실행하고 모든 개체를 출력 스트림에 인쇄하는 최적의 방법을 찾는 것입니다.
2. 해결방안:
예, 스트림은 모든 데이터를 메모리에 저장하지 않고 데이터를 처리하기 위한 일반적인 추상화이므로 이점이 있습니다. 예를 들어 스트림을 HTTP 응답으로 전달합니다.
Spring 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);
64739378