복붙노트

[SPRING] Spring MySQL과 RowCallbackHandler를 사용하여 큰 데이터 세트를 관리하는 방법

SPRING

Spring MySQL과 RowCallbackHandler를 사용하여 큰 데이터 세트를 관리하는 방법

나는 봄과 JdbcTemplate을 사용하여 MySQL의 테이블의 각 행을 검토하려고한다. 착각하지 않으면 다음과 같이 간단해야합니다.

JdbcTemplate template = new JdbcTemplate(datasource);
template.setFetchSize(1);
// template.setFetchSize(Integer.MIN_VALUE) does not work either            
template.query("SELECT * FROM cdr", new RowCallbackHandler() {
  public void processRow(ResultSet rs) throws SQLException {
    System.out.println(rs.getString("src"));
  }
});

나는 그것을 전부 읽으려고하기 때문에 OutOfMemoryError를 얻는다. 어떤 아이디어?

해결법

  1. ==============================

    1.Statement # setFetchSize () javadoc 이미 상태 :

    Statement # setFetchSize () javadoc 이미 상태 :

    운전자는 실제로 힌트를 적용하거나 무시할 수 있습니다. 일부 드라이버는이를 무시하고 일부 드라이버는 직접 적용하며 일부 드라이버는 더 많은 매개 변수가 필요합니다. MySQL JDBC 드라이버는 마지막 범주에 속합니다. MySQL JDBC 드라이버 문서를 확인하면 다음 정보가 표시됩니다 (ResultSet 헤더까지 2/3 스크롤합니다).

    이 문서의 전체 절을 읽으십시오.이 방법의주의 사항도 설명되어 있습니다.

    이를 Spring에서 작동 시키려면 JdbcTemplate을 사용자 정의 구현으로 확장 / 대체해야합니다. 제가 스프링을하지 않았으므로 이것에 대해 자세히 설명 할 수는 없지만 적어도 지금 어디서보아야하는지 알 수 있습니다.

    행운을 빕니다.

  2. ==============================

    2.BalusC가 제공 한 답변을 기반으로 한 Spring 솔루션입니다.

    BalusC가 제공 한 답변을 기반으로 한 Spring 솔루션입니다.

    class StreamingStatementCreator implements PreparedStatementCreator {
        private final String sql;
    
        public StreamingStatementCreator(String sql) {
            this.sql = sql;
        }
    
        @Override
        public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
            final PreparedStatement statement = connection.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
            statement.setFetchSize(Integer.MIN_VALUE);
            return statement;
        }
    }
    

    코드의 어딘가 :

    DataSource dataSource = ...;
    RowCallbackHandler rowHandler = ...;
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    jdbcTemplate.query(new StreamingStatementCreator("SELECT * FROM huge_table"), rowHandler);
    
  3. ==============================

    3.전체 테이블 읽기로 인해 OutOfMemory 오류가 발생한다고 의심되면 쿼리를 분할하지 마십시오. 필터, LIMIT 절 등을 사용하십시오.

    전체 테이블 읽기로 인해 OutOfMemory 오류가 발생한다고 의심되면 쿼리를 분할하지 마십시오. 필터, LIMIT 절 등을 사용하십시오.

  4. from https://stackoverflow.com/questions/2095490/how-to-manage-a-large-dataset-using-spring-mysql-and-rowcallbackhandler by cc-by-sa and MIT license