nakjasabal / MustHaveJSPv2

Must Have JSP 개정판 2번째 원고
4 stars 3 forks source link

05JDBC/ExeUpdate.jsp 와 ExeQuery.jsp 코드에서 의문이 생깁니다. #1

Open Nullgom opened 3 weeks ago

Nullgom commented 3 weeks ago

안녕하세요 MustHave 성낙현의 JSP 자바 웹 프로그래밍을 완독하고 다시 2판을 복습하고 있는 사람입니다. 05장 JDBC 에서 ExeUpdate.jsp 와 ExeQuery.jsp 의 코드에서 PreparedStatement, ResultSet 객체 생성과 닫기에 대해 의문이 들어 글을 남깁니다.

JDBConnect 클래스에서 다음과 같이 멤버변수를 선언하고 있습니다.

class JDBConnect {
      public Connection con; 
      public Statement stmt;
      public PreparedStatement psmt;
      public ResultSet rs; 
      ... 생략 ...

      public void close() {
        try {
            if (rs != null) rs.close();
            if (stmt != null) stmt.close();
            if (psmt != null) psmt.close();
            if (con != null) con.close();

            System.out.println("JDBC 자원 해제");
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

하지만 ExeUpdate.jsp 와 ExeQuery.jsp 코드에서는 PreparedStetement, Statement , ResultSet 객체를 JDBConnect 객체의 변수에 할당해 주는 코드가 없는데 jdbc.close() 위 해당 객체가 자원해제가 정상적으로 진행되는지 알고 싶습니다. // ExeUpdate.jsp 중에서..

               String sql = "INSERT INTO member VALUES (?, ?, ?, sysdate)";
        PreparedStatement psmt = jdbc.con.prepareStatement(sql);
               // jdbc.psmt = psmt;  // jdbc.psmt 변수에 할당해 줄 필요가 없나요 ?
        psmt.setString(1, id);
        psmt.setString(2, pass);
        psmt.setString(3, name);

        // 쿼리 수정
        int inResult = psmt.executeUpdate();
        out.println(inResult + "행이 입력되었습니다.");

        // 연결 닫기
        jdbc.close();  // psmt 와  jdbc.psmt 는 같은 건가요?           

// ExeQuery.jsp 중에서

               // DB예 연결
        JDBConnect jdbc = new JDBConnect();

        // 쿼리문 생성
        String sql = "SELECT id, pass, name, regidate FROM member";
        Statement stmt = jdbc.con.createStatement();
        // jdbc.stmt = stmt;  // ??
        // 쿼리 수행
        ResultSet rs = stmt.executeQuery(sql);
            // jdbc.rs = rs; // ??
        // 결과 확인(웹 페이지에 출력)
        while (rs.next()) {
            String id   = rs.getString(1);
            String pw   = rs.getString(2);
            String name = rs.getString("name");
            java.sql.Date regidate = rs.getDate("regidate");

            out.println(String.format("%s %s %s %s", id, pw, name, regidate) + "<br />");                   
        }

        // 연결 닫기
        jdbc.close();  // 여기서 stmt 와 rs 은 자원 해제(close())가 되는 건가요 ?

그리고 JDBConect 클래스에서 PreparedStatement 와 Statement 멤버 변수를 선언했는데.. PreparedStatement의 상위 클래스는 Statement 인데 Statement 하나만 선언하여 PreparedStatement 객체를 할당 받으면 되는 것이 아닌지 합니다.

nakjasabal commented 3 weeks ago

안녕하세요? 독자님.. 저자 성낙현 입니다. 먼저 저의 책을 통해 열심히 공부하고 계시다니 감사의 말씀 먼저 드립니다.

질문 내용을 살펴보니 독자님의 의견이 옳은것 같습니다. Statement stmt = jdbc.con.createStatement();
위와 같이 작성하면 JDBConnect 클래스의 멤버변수를 사용하는것이 아닌 Statement 인스턴스를 새롭게 생성하는 것입니다. ResultSet rs = jdbc.stmt.executeQuery(sql);
이 문장도 마찬가지 이구요.. 그래서 아래와 같이 수정해야할것 같습니다. jdbc.stmt = jdbc.con.createStatement(); jdbc.rs = jdbc.stmt.executeQuery(sql);

이 부분은 집필할 당시에 놓쳤던것 같습니다. 정확한 지적 감사드립니다. 수정한 코드는 github에 적용해 두었습니다.

두번째 질문은 ... PreparedStatement의 상위 클래스는 Statement 인데 Statement 하나만 선언하여 PreparedStatement 객체를 할당 받으면 되는 것이 아닌지 합니다. ==> Statement 가 상위 인터페이스는 맞지만 이렇게 하면 코드의 명시성이 떨어집니다. stmt 멤버변수로 정적쿼리, 동적쿼리를 다 처리하는것처럼 보이게됩니다. Statement 인터페이스는 정적쿼리, PreparedStatement 인터페이스는 동적쿼리를 처리하므로 가독성이 높은 명시적인 코드를 위해서는 별도로 사용하는것이 좋습니다.

감사합니다.


-----Original Message----- From: "Won @.> To: @.>; Cc: @.***>; Sent: 2024-06-14 (금) 20:14:28 (GMT+09:00) Subject: [nakjasabal/MustHaveJSPv2] 05JDBC/ExeUpdate.jsp 와 ExeQuery.jsp 코드에서 의문이 생깁니다. (Issue #1)

안녕하세요 MustHave 성낙현의 JSP 자바 웹 프로그래밍을 완독하고 다시 2판을 복습하고 있는 사람입니다. 05장 JDBC 에서 ExeUpdate.jsp 와 ExeQuery.jsp 의 코드에서 PreparedStatement, ResultSet 객체 생성과 닫기에 대해 의문이 들어 글을 남깁니다. JDBConnect 클래스에서 다음과 같이 멤버변수를 선언하고 있습니다. class JDBConnect { public Connection con; public Statement stmt; public PreparedStatement psmt; public ResultSet rs; ... 생략 ... public void close() { try { if (rs != null) rs.close(); if (stmt != null) stmt.close(); if (psmt != null) psmt.close(); if (con != null) con.close(); System.out.println("JDBC 자원 해제"); } catch (SQLException e) { e.printStackTrace(); } } } 하지만 ExeUpdate.jsp 와 ExeQuery.jsp 코드에서는 PreparedStetement, Statement , ResultSet 객체를 JDBConnect 객체의 변수에 할당해 주는 코드가 없는데 jdbc.close() 위 해당 객체가 자원해제가 정상적으로 진행되는지 알고 싶습니다. // ExeUpdate.jsp 중에서.. String sql = "INSERT INTO member VALUES (?, ?, ?, sysdate)"; PreparedStatement psmt = jdbc.con.prepareStatement(sql); // jdbc.psmt = psmt; // jdbc.psmt 변수에 할당해 줄 필요가 없나요 ? psmt.setString(1, id); psmt.setString(2, pass); psmt.setString(3, name); // 쿼리 수정 int inResult = psmt.executeUpdate(); out.println(inResult + "행이 입력되었습니다."); // 연결 닫기 jdbc.close(); // psmt 와 jdbc.psmt 는 같은 건가요? // ExeQuery.jsp 중에서 // DB예 연결 JDBConnect jdbc = new JDBConnect(); // 쿼리문 생성 String sql = "SELECT id, pass, name, regidate FROM member"; Statement stmt = jdbc.con.createStatement(); // jdbc.stmt = stmt; // ?? // 쿼리 수행 ResultSet rs = stmt.executeQuery(sql); // jdbc.rs = rs; // ?? // 결과 확인(웹 페이지에 출력) while (rs.next()) { String id = rs.getString(1); String pw = rs.getString(2); String name = rs.getString("name"); java.sql.Date regidate = rs.getDate("regidate"); out.println(String.format("%s %s %s %s", id, pw, name, regidate) + "
"); } // 연결 닫기 jdbc.close(); // 여기서 stmt 와 rs 은 자원 해제(close())가 되는 건가요 ? 그리고 JDBConect 클래스에서 PreparedStatement 와 Statement 멤버 변수를 선언했는데.. PreparedStatement의 상위 클래스는 Statement 인데 Statement 하나만 선언하여 PreparedStatement 객체를 할당 받으면 되는 것이 아닌지 합니다. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you are subscribed to this thread.Message ID: @.***>