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