2011-08-30 3 views
3

SELECT 몇 개를 연속적으로 실행 중이며, PreparedStatement을 어떻게 처리해야하는지 궁금합니다.연속 PreparedStatement 우수 사례

예제 코드 :

//Connection conn is already declared 
PreparedStatement pstmt = null; 
ResultSet rset = null; 
try { 
    String sql = "SELECT ..."; 
    pstmt = conn.prepareStatement(sql); 
    pstmt.setString(1, someVar); 

    rset = pstmt.executeQuery(); 
    // Use ResultSet 

    // A different query 
    sql = "SELECT ..."; 
    pstmt = conn.prepareStatement(sql); 
    pstmt.setString(1, someVar); 

    rset = pstmt.executeQuery(); 
    // Use ResultSet 
} catch (SQLException e) { 
    // Handle 
} finally { 
    if (rset != null) 
    rset.close(); 
    if (pstmt != null) 
    pstmt.close(); 
    if (conn != null) 
    conn.close(); 
} 

는 이제 질문은/각 사용 후 PreparedStatement의를 닫 다른 문을 사용하는 것이 좋을 것이다하거나 전혀 차이가없는 것입니까?

항상 같은 검색어를 사용하는 PreparedStatement을 재사용하는 방법에 대한 정보가 있지만 다른 검색어를 사용하는 것은 확실하지 않습니다.

+0

저는이 예제에서 동일한 것을 사용하고 2를 사용하는 것의 차이가 무시할 수있을 것이라고 확신합니다. 그러나 루프에서 여러 번 사용하는 경우 데이터베이스에 매번 쿼리를 다시 컴파일 할 필요가 없으므로 두 개를 사용하는 것이 좋습니다. – Shaded

+0

다른 쿼리를 사용하는 경우 여러 문을 사용하거나 명령문에 스위치를 작성할 필요가 있습니다 (가능한 경우). 나는 유지 관리가 쉽고 읽기 쉬운 옵션을 사용하고 여러 문을 사용합니다. – Thomas

+2

이것은 꽤 이상한 구조입니다. 결과가 하나의 최종 결과에서 관련/결합 되는가? 예? 당신은 SQL'JOIN' 절에 익숙합니까? 나는 당신이 하나의 SQL 쿼리로 끝날 수 있도록 그것을 배우는 데 시간을 투자 할 것입니다. 또는 완전히 독립적 인 두 개의 쿼리 인 경우 별도의 메서드 본문에서 실행합니다. – BalusC

답변

9

PreparedStatement을 사용하고 있지 않으므로 팩토리 메서드 Connection.prepareStatement은 사용자가 전화 할 때마다 새 인스턴스를 반환합니다. 은 ResultSet과 동일하게 작동합니다. 당신은 단지 같은 변수를 사용하고 있습니다.

즉,이 메소드가 호출 될 때마다 닫히지 않을 리소스 (첫 번째는 PreparedStatementResultSet)가 누출됨을 의미합니다.

내 권장 사항은이 데이터베이스 자원을 올바르게 처리하고 코드를 두 가지 방법으로 나눌 수있는 Spring의 JdbcTemplate을 사용하는 것입니다.

+1

즉, 여러 명령문 및 결과 집합에 대해 별도의 지역 변수를 사용하고'finally '에 * all *을 닫을 필요가 있습니다. – BalusC

+0

+1, 좋은 대답. – Johan

+0

이 최상위 대답은 당신이'ResultSet'을 재사용 할 수 있다고 말합니다. @stackoverflow.com/questions/12903115/reusing-resultset – ethanjyx