jsp :: Commons-DbUtils

2008.03.06 11:07
 
출처 Min Gun | 민군
원문 http://blog.naver.com/levin01/100011050694

Commons-DbUtils

 

I. 어디서 다운을 받나요?


http://jakarta.apache.org/site/downloads/downloads_commons-dbutils.cgi


II. 설치는 어떻게 하나요?

다운 받은 commons-beanutils.jar는 자신의 /WEB-INF/lib/ 에 복사합니다


III. DbUtils란 무엇인가요?

DbUtils는 JDBC 작업을 좀더 쉽게 할수있도록 해주는 작은 클래스 집합입니다.


IV. 왜 DbUtils를 사용해야 하는가요?

① resource 누출에 대한 어떠한 가능성도 없습니다
  JDBC코딩을 하는데 있어서 쉽지않고 양도 만만치 않으며 지루해 지기 쉽습니다
  이러다 보면 자기도 모르게 Connection 누수를 발생시킬수 있는데 이러한 가능성을 배재해 줍니다


② 코드의 가독성이 높아집니다
  데이터베이스 처리하는데 필요한 코드의 양을 절대적으로 줄여야 합니다.
  남아있는 코드로 당신의 의도를 정확하게 나타내어야 합니다.


③ ResultSet으로 부터 JavaBean property로 세팅을 해줍니다!
  더이상 setter메소드를 이용하여 ResultSet으로부터 컬럼값을 가져오는 코딩을 하지 않아도 됩니다
  ResultSet 각각의 row는 bean instance의 에 완벽하게 전달해 줍니다


V. 어떻게 사용하나요?

  Connection, Statement, ResultSet 의 close를 간단하게!

    이럴때는 org.apache.commons.dbutils.DbUtils 클래스를 이용하자!

    이 클래스는 모두 static 메소드들로 구성되어있습니다

   

    사용예)

    DbUtils.close(conn);  
    DbUtils.close(stmt);
    DbUtils.close(rs);
    DbUtils.closeQuietly(conn);
    DbUtils.closeQuietly(stmt);
    DbUtils.closeQuietly(rs);
    DbUtils.closeQuietly(conn, stmt, rs);
    DbUtils.commitAndClose(conn);

    DbUtils.commitAndCloseQuietly(conn);
    DbUtils.loadDriver("com.mysql.jdbc.Driver");
    DbUtils.rollback(conn);


    closeQuietly 메소드처럼 뒤에 Quietly라고 붙어 있는 메소드는 익셉션 처리는 자체적으로 처리합니다,

    즉 자신을 call한곳으로 throw 하지 않습니다

    commitAndCloses는 connection을 commit 후 close 하며 rollback는 connection을 rollback 합니다

    loadDriver 는 JDBC 드라이버를 로딩 합니다


 파일로 저장된 SQL을 사용하자!

    이럴 때는 org.apache.commons.dbutils.QueryLoader 클래스를 이용합니다

    이 클래스는 SingleTone 패턴의 클래스입니다

    즉 파일로 저장된 SQL을 읽어 HashMap으로 로드하는 클래스 입니다

   

    사용예)

    QueryLoader queryloader = QueryLoader.getInstance();   //싱글톤
    HashMap hashmap = queryloader.load("sql");      

    queryloader.upload("sql");


    queryloader는 싱클톤이므로 위와같이 객체를 얻어옵니다

    load 함수는 Properties 클래스를 이용하여 sql.properties 파일을 읽어

    HashMap으로 저장하여 리턴하여 줍니다

    unload는 load시 따로 메모리에 저장해 놓았던 sql 정보를 해제합니다


  Setter함수로 더이상 머리 아프지 말자!

   이럴때는 org.apache.commons.dbutils.QueryRunner 클래스를 이용합니다


   사용예)

    ...  

    BoardVO boardVO = null;

    ArrayList arraylist = new ArrayList();

 

    resultset = statement.executeQuery("SELECT * FROM board_t");

    while (resultset.next()) {

        boardVO = new BoardVO();

        boardVO.setTitle("title");

        boardVO.setContent("content");

        boardVO.setWriter("writer");

        arraylist.add(boardVO);       

    }

    ..

   와 같은 코드는 다음과 같이 간략화 됩니다


   ResultSetHandler rsh= new BeanListHandler(BoardVO.class);
   QueryRunner queryRunner = new QueryRunner();

   List list = (List)queryRunner.query(conn, "SELECT * FROM board_t", rsh);


   정말 간단해 집니다 만약 테이블에 컬럼이 30~40개가 된다면..

   select 한문장 할려면 코드수가 몇십줄 입니다. 더이상 노가다 하지 맙시다~


   QueryRunner는 다음과 같은 함수를 지원합니다

   사용예)

  QueryRunner queryrunner = new QueryRunner();
   QueryRunner queryrunner = new QueryRunner(DataSource ds);
//datasource를 바로 이용할 수 있다

  queryRunner.query(Connection conn, String sql, ResultSetHandler rsh)
   queryRunner.query(Connection conn, String sql, Object param, ResultSetHandler rsh)
   queryRunner.query(Connection conn, String sql, Object[] params, ResultSetHandler rsh)


   여기서 말하는 Object param은 파라미터 전달시 사용됩니다

   ArrayList params = new ArrayList();
   params.add("100");

   params.add("200");

   ResultSetHandler rsh = new BeanListHandler(BoardVO.class);
   QueryRunner queryRunner = new QueryRunner();

   List list = (List)queryRunner.query(conn, "SELECT * FROM board_t WHERE boardNo > ? and boardNo < ?", params.toArray(), rsh);


   select 뿐만 아니라 update, delete역시 가능합니다

   사용예)

   QueryRunner queryRunner = new QueryRunner();

   queryRunner.update(Connection conn, String sql)
   queryRunner.update(Connection conn, String sql, Object param)
   queryRunner.update(Connection conn, String sql, Object params[])

  

   ArrayList params = new ArrayList();
   params.add(boardId);
   queryRunner.update(connection, "UPDATE board_t SET read = read + 1 WHERE boardNo = ?", params.toArray());

   와 같이 사용할 수 있습니다



VI. 샘플코드

public class DbUtilsExample() {

   public static void main(String[] args) {

       HashMap map = QueryLoader.getInstance().load("sql");  // (주의) load함수는 실행할때마다 파일을 읽습니다


       Connection conn = null;

       try {

           DbUtils.loadDriver("com.mysql.jdbc.Driver");

           conn = DriverManager.getConnection("jdbc:mysql://localhost/mysql", "root", "");


           ArrayList params = new ArrayList();
           params.add(args[0]);


           ResultSetHandler rsh = new BeanListHandler(BoardVO.class);

           QueryRunner qr = new QueryRunner();

           List list = qr.query(conn, (String)map.get("select"), params.toArray(), rsh);


           for (int i = 0; i < list.size(); i++) {

               BoardVO board = (BoardV)list.get(i);

               System.out.println(board.getTitle());

               System.out.println(board.getContent());

               System.out.println(board.getWriter());

          )

       } catch (Exception e) {

           System.out.println(e);

       } finally {

           DbUtils.closeQuitely(conn);

       }

   }

}



신고
Posted by 나비 나비:D

select를 했으면, insert, update, delete를 사용하는 것을 알아본다.

Apache common DbUtils 사용법 1에서 사용한 방법과 거의 동일한 방법으로 사용을 한다.

먼저 insert를 한번 해보자
insert into testdb(name, addr) values(’Park’ ‘Seoul’)
이런 문장을 가지고 코드를 만들어 보면 아래와 같다.
public int insert()
{
int result = 0;
int index = 0;
String query = “insert into testdb(name, addr) values(:name,:addr)”;
try
{
QueryRunner runner = new QueryRunner();
Vector v = new Vector();
v.add(index++, ‘Park’);
v.add(index++, ‘Seoul’);
result = runner.update(conn, query, v.toArray());
}catch(SQLException ex)
{
log.error(ex);
log.error(”[SQL:]” + query);
throw ex;
}
return result;
}

리턴값이 0보다 크면 정상적으로 insert된다. 여기서 유의해 볼것은 Vector에 입력되는 값인데, 반드시 sql의 구조와 동일한 순서로 되어야 한다. QueryRunner class에서 Vector와 query를 가지고 PreparedStatement를 재구성하기 때문이다.

update, delete는 위에서 query만 변경되면 된다. 간단하지 아니한가??

작성자 : 박남준(criticalbug@gmail.com)

신고
Posted by 나비 나비:D

DB를 사용할때 가장 속썩이는 부분이 DB connection pool과 Connection, PreparedStatment, ResultSet 이 클래스들 일것이다.

사용을 했으면 반드시 닫아 주어야 시스템에 문제가 생기지 않는다.

일반적으로 select를 사용해보자

public static void main(String args[]) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String tableName = “”;
try {
conn = ConnectionManager.getConnection();
pstmt = conn.prepareStatement(”select * from tab”);
rs = pstmt.executeQuery();
while(rs.next()) {
tableName = String.format(”tname:%s, tabtype:%s”, rs.getString(1), rs.getString(2));
System.out.println(tableName);
}
} catch(Exception e) {
e.printStackTrace();
} finally {
if(rs != null) try { rs.close(); } catch(Exception e) {}
if(pstmt != null) try { pstmt.close(); } catch(Exception e) {}
if(conn != null) try { conn.close(); } catch(Exception e) {}
}
}

상당히 익숙한 코드들이다. 여기서 유의해 볼것은 while이 있는 부분인데 rs에 있는 데이터의 크기도 크기지만, set을 이용해서 코딩하는것 자체가 한마디로 삽질인데, 이것을 dbutils을 사용해서 한번 줄여 보자

먼저 데이터의 구조를 가지고 있는 클래스를 하나 만든다

public static class TabDTO {
private String tname = “”;
private String tabtype = “”;
public String getTabtype() {
return tabtype;
}
public void setTabtype(String tabtype) {
this.tabtype = tabtype;
}
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}

}

이것을 사용해서 위에서 연습한 것과 동일한 것을 만들어 보자

public static void main(String args[]) {
Connection conn = null;
int index = 0;
String tableName = “”;
String query = “select * from tab”;
List list = new ArrayList();

try {
conn = ConnectionManager.getConnection();
QueryRunner runner = new QueryRunner();
ResultSetHandler rsh = new BeanListHandler(TabDTO.class); //레코드 여러건
//ResultSetHandler rsh = new BeanHandler(TabDTO.class); //레코드 1건
Vector v = new Vector();
//v.add(index++, “TBLBANK”);
list = (List)runner.query(conn, query, v.toArray(), rsh);
//TabDTO dto = (TabDTO)runner.query(conn, query, v.toArray(), rsh);

Iterator iter = list.iterator();
while(iter.hasNext()) {
TabDTO dto = new TabDTO();
dto = (TabDTO)iter.next();
tableName = String.format(”tname:%s, tabtype:%s”, dto.getTname(), dto.getTabtype());
System.out.println(tableName);
}
} catch(Exception e) {
e.printStackTrace();
} finally {
if(conn != null) try { conn.close(); } catch(Exception e) {}
}
}
어떤가? 더 어려워졌다고 느끼는 분도 있을것이다. 누구나 그러하니까..

중점적으로 볼것은 QueryRunner, ResultSetHandler 이것들은 항상 같이 쓰이고 BeanListHandler는 데이터가 여러건 즉, 리스트 형태일때 사용한다. QueryRunner의 속을 깊이 들여다 보면, query가 여러개 정의되어 있는데 시간이 있으면 한번 들여다 보는것을 권장한다. 그다음에 Vector로 정의된 부분은 dynamic query,즉 PreparedStatement에 사용되는 것을 순서대로 add하여 사용한다. 참고로 query가 ~~where abe=? and def=? 이렇게 되어 있다면 v.add(1, “a”); v.add(2, “b”) 이렇게 되겠다.

조금전에 QueryRunner의 query를 살펴보았다면, query의 역할을 알 것이고 이것은 Object를 리턴함으로 List로 casting하여 사용하게 된다.

글을 처음 쓰는거라 손가락 무지아프다. 다음편에는 insert, update, delete를 알아보자

작성자 : 박남준(criticalbug@gmail.com)

신고
Posted by 나비 나비:D
출처 : http://www.okjsp.pe.kr/bbs?act=VIEW&bbs=bbs4&keyfield=content&keyword=&seq=48115&pg=0

jakarta commons DbUtils 간단한 사용법

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 책에서 많이 참고했습니다.

신고
Posted by 나비 나비:D

BLOG main image
by 나비:D

공지사항

카테고리

분류 전체보기 (278)
Programming? (0)
----------------------------- (0)
나비의삽질 (5)
Application (177)
SQL (51)
Web (27)
etc. (14)
Omnia (0)
---------------------------.. (0)

글 보관함

달력

«   2017/12   »
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
Total : 894,884
Today : 42 Yesterday : 238