2011-12-12 1 views
1

준비된 문을 사용하여 데이터베이스를 쿼리하려고합니다.PreparedStatement를 사용하여 데이터베이스를 쿼리하려고하면 ResultSet이 닫히지 않아야합니다.

public ResultSet preparedQueryContactsWhereAccount(String accountName) throws SQLException { 
    PreparedStatement statment = null; 
    ResultSet rs = null; 
    String statString = "SELECT * FROM contacts WHERE account_name = ?"; 

    try { 
     statment = mConn.prepareStatement(statString); 
     statment.setString(1, accountName); 
     rs = statment.executeQuery(); 
    } catch(SQLException e) { 
     e.printStackTrace(); 
    } 
    if(statment != null) { 
     statment.close(); 
    } 
    return rs; 
} 

그러나이 폐쇄 된 ResultSet을 반환 : 처음에,이 있었다. 나는 약간의 독서를했고, 때로는 문장이 닫히면 결과 집합도 닫힐 수 있다는 것을 알게되었습니다. 그래서 나는 이것을 시도했다 :

public MasterEntry preparedQueryContactsWhereAccount(String accountName, MasterEntry entry) throws SQLException, IllegalAccessException { 
    PreparedStatement prepStat = null; 
    ResultSet rs = null; 
    String statString = "SELECT * FROM contacts WHERE account_name = ?"; 

    try { 
     prepStat = mConn.prepareStatement(statString); 
     prepStat.setString(1, accountName); 
     rs = prepStat.executeQuery(); 
    } catch(Exception e) { 
     e.printStackTrace(); 
     System.err.println("Statement failed."); 
    } 
    if(rs.isClosed()) { 
     System.out.println("fail"); 
     throw new IllegalAccessException("closed"); 
    } 
    else { 
     entry.setmFirstName(rs.getString("first_name")); 
     entry.setmLastName(rs.getString("last_name")); 
     entry.setmEmail(rs.getString("email_address")); 
     rs.close(); 
     prepStat.close(); 
    } 
    return entry; 

} 

ResultSet 데이터가 모두 메소드 내에서 처리 될 수 있도록 약간의 프로세스 재구성. 이 경우 IllegalAccessException이 표시되고 ResultSet은 닫힙니다.

나는이 같은 쿼리를 (같은 안전하지 않습니다 및 아포스트로피와 같은 문자를 처리 할 수 ​​없습니다) 간단한 방법으로 일을 시도

:

쿼리로 "SELECT * FROM contacts WHERE account_name = '" + accountName + "'"

같은 계정 이름 문자열에 해당

public ResultSet makeQuery(String query) { 
    ResultSet rs = null; 
    try { 
     rs = mStat.executeQuery(query); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     System.out.println("Problem in query: " + query); 
    } 
    return rs; 
} 

나는 preparedQuery 메소드에서 사용했다. 물론이 방법은 제대로 작동하지만 그 안에 어포 스트로피가있는 accountName은 실패합니다. 준비된 성명서로이 작업을 수행하고 싶습니다.하지만 그 사실을 파악할 수는 없습니다. 어떤 충고? 고마워.

답변

2

코드가 괜찮은 것처럼 보이지만 rs.next() 명령이 누락되었습니다. 특정 행으로 설정되지 않은 결과 세트를 읽으려고 시도 중이므로 IllegalStateException을 수신하고 있습니다.

1

권장하지 않습니다.

ResultSet을 반환하는 대신 즉시 루프를 반복하여 모든 결과를 가져 와서 다른 것으로 넘겨야합니다. 그런 다음 닫아야합니다.

Statements, ResultSets 및 Connections와 같은 항목을 전달하면 결과적으로 리소스 누수가 발생할 수 있습니다. 코드 누락을 방지하기 위해 불필요한 복잡성을 생성하는 것은 물론입니다. 그들은 누출을 피하기 위해 모든 블록을 열어 사용하고 즉시 닫아야합니다. 그러한 메소드에서 리턴 된 것은 라이프 사이클 및 관련 자원을 가진 일부 DB 오브젝트에 묶여서는 안됩니다.

당신은이 충고를 할 필요가 없지만, 당신이한다면 당신의 삶이 더 쉬울 것이라고 저는 정말로 믿습니다.

0

이미 사용해 보았지만 필요한 기능이없는 경우 JDBC를 직접 사용하지 않는 것이 좋습니다. 대신에 Hibernate, iBatis (은퇴되었지만 여전히 기능적) 또는 myBatis (iBatis를 따르기)를 가져 와서 JDBC 작업을 처리하게하십시오. 이러한 ORM 도구는 홈스푼 프로젝트보다 리소스를 관리하는 데 더 효과적 일 수 있습니다.