요즘 보고 있는 책 Core EJB 책을 보다보니 Stream 을 닫는 부분이 잘못 나와있다.
(뭐, 이거 빼고는 아직은 읽기에 부담스럽지 않고 만족스럽다..)
어찌 했냐면,
try {
...
} catch(..) {
...
} finally {
if (writer != null) writer.close();
if (reader != null) reader.close();
if (socket != null) socket.close();
}
위와 같이 했는데, 이렇게 하면 안된다.
위와 같이하면 첫번째 writer.close() 에서 예외가 발생하면 그 이후의 다른 close() 문들은 전혀 실행되지 않고 빠져나가 버려 리소스 누수가 발생하게 된다.
이것은 스트림이나 소켓 뿐만 아니라 JDBC Connection 에서도 마찬가지 이다.
그러므로 다음과 같이 바꿔야만 쓰겠다.
try {
...
} catch(..) {
...
} finally {
if (writer != null) {
try { writer.close(); } catch (Exception ex) {}
}
if (reader != null) {
try { reader.close(); } catch (Exception ex) {}
}
if (socket != null) {
try { socket.close(); } catch (Exception ex) {}
}
}
if / for / while 문 등은 비록 실행할 문장이 한 개 뿐이라도 괄호를 치는 것을 원칙으로 한다.
그리고 일일이 귀찮더라도 다 try/catch 안에 .close() 문을 넣어야 안전하게 리소스를 닫는 것이 된다.
Jakarta Commons DBUtils에는 저런 귀찮은 try/catch 없이 메소드 하나 호출로 JDBC 리소스를 닫아주는 메소드가 있다.
DbUtils.closeQuietly()를 한번 사용해 보시라.
----------------------------------------------------------------------------------------------------------
출처 : http://www.okjsp.pe.kr/bbs?act=VIEW&bbs=bbs4&keyfield=content&keyword=&seq=48115&pg=0
Commons DbUtils : 데이터베이스 사용에 있어서 단순노가다로 이루어지던 많은 작업을 편리하게 해준다. 그동안 "이거 귀찮은데 유틸로 뽑아놓을까?" 아니면 "우씨~ 이런 노가다" 하던 부분이 한방에 해결됐다. 단순한 유틸 패키지이기에 사용법도 간단하고 편리하다.
//1. JDBC 드라이버 로딩을 간략화(로딩 성공시 true 반환)
if (!DbUtils.loadDriver("com.mysql.jdbc.Driver")) {
System.out.println("Failed Loading JDBC Driver!");
System.exit(0);
}
//2. Connection, ResultSet, Statement 등의 close를 간단하게
(null 확인 - > 예외처리의 과정을 간단하게)
DbUtils.closeQuietly(connection);
//3. QueryRunner - 쿼리문 수행
- SELECT
query(Connection conn, String sql, ResultSetHandler rsh)
query(Connection conn, String sql, Object param, ResultSetHandler rsh)
query(Connection conn, String sql, Object[] params, ResultSetHandler rsh) 등
param은 PreparedStatement의 ?에 해당 .. 2개 이상은 배열을 만들어서 전달
- INSERT, UPDATE, DELETE의
int update(Connection conn, String sql)
int update(Conneciton conn, String sql, Object param) 등
executeUpdate()와 사용법 동일
//4. ResultSetHandler - 빈이나 맵을 만들어서 ResultRet에서 읽어들여 넣어주는 노가다여 안녕~!
BeanHandler, BeanListHandler, MapHandler, MapListHandler
예)
String query = "SELECT * FROM user WHERE name = ?";
User user = null;
ResultSetHandler rsh = new BeanHandler(User.class);
QueryRunner runner = new QueryRunner();
user = (User) runner.query(conn, query, "홍길동", rsh);
-----------
import java.sql.*;
import org.apache.commons.dbutils.DbUtils;
public class CommonsDBUtilExample {
public static void main(String[] args) {
Connection connection = null;
String url = "jdbc:mysql://localhost/mysql";
String user = "root";
String password = "";
if (!DbUtils.loadDriver("com.mysql.jdbc.Driver")) {
System.out.println("Failed Loading JDBC Driver!");
System.exit(0);
}
try {
connection = DriverManager.getConnection(url, user, password);
System.out.println("Connection successful!!");
Statement select = connection.createStatement();
ResultSet rs = select.executeQuery("select * from user");
while (rs.next()) {
System.out.println(rs.getString(1));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DbUtils.closeQuietly(connection);
}
}
}
------------
그냥 사용법 까먹지 않기위해 Blog에 적어둔거 올려봅니다. Jakarta Project 책에서 많이 참고했습니다.
'Java' 카테고리의 다른 글
알면 편리한 SAX Parser (0) | 2010.04.20 |
---|---|
자바 프로그램이 돌아가는데 딜레이를 주자. (0) | 2010.04.16 |
상속과 다형성 (0) | 2009.12.27 |
JavaScript와 Java를 이용한 웹어플리케이션에서 JSON을 이용한 통신방법을 보겠습니다 (0) | 2009.12.11 |
자꾸 까먹는 3항 연산자. (0) | 2009.12.11 |