복붙노트

[SQL] 자바 - 연결 닫은 후 결과 집합 사용할 수 없습니다

SQL

자바 - 연결 닫은 후 결과 집합 사용할 수 없습니다

나는 MySQL의에 연결을 닫기에 문제가 있습니다.

나는 오류를 받고 있어요 :

내 코드 :

public static ResultSet sqlquery (String query)
{
 ResultSet rs=null;
 Connection connection=null;
 Statement st=null;
 try{   
     Class.forName("com.mysql.jdbc.Driver");
     connection = DriverManager.getConnection("databaseadress","username","password");
     st = connection.createStatement();  
     rs = st.executeQuery(query);

    }catch(SQLException e){System.out.println("SQL error: " + e);}
      catch(Exception e){System.out.println("Error: " + e);}
       finally {
       try{
          if(rs != null) rs.close();
          if(st!= null) st.close();
          if(connection != null)  connection.close();
  }catch(SQLException e){System.out.println("SQL error : " + e);}

    }
     return rs;
}

해결법

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

    1.이것은 JDBC가 작동하는 방식이다. 코드에서 당신은의 ResultSet과의 ResultSet가 더 이상 사용할 수없는 후 연결을 마감했다. 당신이 사용할 수하려면 당신은 (그리고 연결)를 열린 상태로해야합니다.

    이것은 JDBC가 작동하는 방식이다. 코드에서 당신은의 ResultSet과의 ResultSet가 더 이상 사용할 수없는 후 연결을 마감했다. 당신이 사용할 수하려면 당신은 (그리고 연결)를 열린 상태로해야합니다.

    당신이 결과 집합을 반환 할 경우 호출 방법은 연결을 제공하므로 그러나, 당신은 당신의 코드를 리팩토링해야한다.

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

    2.모든 열망을 가져 오기 위해 그들 중 너무 많은이있을 수 있기 때문에 JDBC는 ResultSet의 다시 쿼리의 모든 결과를 가져 오지 않습니다. 대신 당신이 결과를 검색하는 데 사용할 수있는 무언가를 제공하지만, 어느 때 연결 닫히고 도망 간다. 데이터베이스 연결을 닫은 후 당신의 방법에서 그것을 다시 전달 때, 아무것도 그것을 사용할 수 없습니다.

    모든 열망을 가져 오기 위해 그들 중 너무 많은이있을 수 있기 때문에 JDBC는 ResultSet의 다시 쿼리의 모든 결과를 가져 오지 않습니다. 대신 당신이 결과를 검색하는 데 사용할 수있는 무언가를 제공하지만, 어느 때 연결 닫히고 도망 간다. 데이터베이스 연결을 닫은 후 당신의 방법에서 그것을 다시 전달 때, 아무것도 그것을 사용할 수 없습니다.

    당신이 대신 할 수있는 것은 개체 또는 개체의 컬렉션을 채우는이 방법을 사용하는 결과 집합이 있고, 그 인구 객체 등을 전달하는 것입니다.

    당신이 (결과 집합의 현재의 행으로 채워 객체를 사용하여 결과를 받아 다시 전달)을 RowMapper를 전달하도록 코드를 변경하고 다시 통과하는 컨테이너 개체를 채우는 것을 사용하는 경우, 당신은 뭔가를해야합니다 당신이 작성한 것을 무엇으로 재사용이하지만 통화가 종료 된 후에 연결이 열린 상태로있는에 의존하지 않기 때문에 이는 실제로 작동합니다.

    다음은 예제 코드가있는 RowMapper를 사용하여 다시 작성있어, 불필요한 예외 잡기 제거, 경우에 폐쇄하기에서 연결을 방지하는 버그를 수정 얻을 :

    public static List<T> sqlquery (String query, RowMapper<T> rowMapper) throws SQLException
    {
        Connection connection=null;
        Statement st=null;
        ResultSet rs=null;
        // don't need Class.forName anymore with type4 driver     
        connection = DriverManager.getConnection("databaseadress","username","password");
        st = connection.createStatement();  
        rs = st.executeQuery(query);
        List<T> list = new ArrayList<T>();
        while (rs.next()) {
            list.add(rowMapper.mapRow(rs));
        }
        // don't let exception thrown on close of
        // statement or resultset prevent the
        // connection from getting closed
        if(rs != null) 
            try {rs.close()} catch (SQLException e){log.info(e);}
        if(st!= null) 
            try {st.close()} catch (SQLException e){log.info(e);}
        if(connection != null)  
            try {connection.close()} catch (SQLException e){log.info(e);}
        return list;
    }
    

    위의 그림과 같이 각 예외가 가까이 개별적으로 던져 잡을 수없는 경우에는 문 또는 결과 집합 중 하나가 가까이에 예외를 던질 경우 연결을 닫 실패 위험이 있습니다.

    이것은 같은 RowMapper의 정의, 스프링 JDBC가 무엇 비슷합니다 :

    public interface RowMapper<T> {
        T mapRow(ResultSet, int rowNum) throws SQLException;
    }
    

    다음 단계는 당신이하지 않아도 쿼리를 매개 변수화 할 것입니다 SQL 주입에 대한 인용이나 걱정에서 서라운드 매개 변수 값. 스프링 JDBC이를 처리하는 방법의 예를 들어이 답변을 참조하십시오. 여기에 장기 대답은 스프링 JDBC 또는 단편을 재발견하는 것보다 비슷한 채택하는 것이 좋습니다 것입니다.

  3. ==============================

    3.연결이 종료되면 더 이상 자원 (문, 준비된 명령문, 결과 집합) 중 하나를 사용할 수 없습니다, 그들 모두가 자동으로 닫힙니다. 그래서 당신은 자원이 열려있는 동안 당신의 모든 처리를 할 필요가있다.

    연결이 종료되면 더 이상 자원 (문, 준비된 명령문, 결과 집합) 중 하나를 사용할 수 없습니다, 그들 모두가 자동으로 닫힙니다. 그래서 당신은 자원이 열려있는 동안 당신의 모든 처리를 할 필요가있다.

    충전하고, DTO, 당신은 당신이 살아 연결을 유지하지 않고 필요한 데이터를 가질 수있는이 방법을 돌아보십시오.

  4. from https://stackoverflow.com/questions/25493837/java-cant-use-resultset-after-connection-close by cc-by-sa and MIT license