Spring 프레임워크 워크북 정리노트 - Chapter4. Spring JDBC :: 스프링(spring)/아이바티스(IBatis)/하이버네이트(Hibernate)[SSISO Community]
 
SSISO 카페 SSISO Source SSISO 구직 SSISO 쇼핑몰 SSISO 맛집
추천검색어 : JUnit   Log4j   ajax   spring   struts   struts-config.xml   Synchronized   책정보   Ajax 마스터하기   우측부분

스프링(spring)/아이바티스(IBatis)/하이버네이트(Hibernate)
[1]
등록일:2008-06-11 16:47:21 (0%)
작성자:
제목:Spring 프레임워크 워크북 정리노트 - Chapter4. Spring JDBC

Chapter4. Spring JDBC

기존의 JDBC를 이용하여 퍼시스텀스 계층을 구현할 때 Connection 생성, PreparedStatement 생성, SQLException 처리와 같이 중복적으로 구현해야 하는 소스 코드가 너무 많았다.

Spring 프레임워크는 이러한 문제점(?)을 해결하기 위해 JDBC를 추상화한 API를 새롭게 제공하고 있다.
이것이 Spring 프레임워크가 제공하고 있는 Spring JDBC 이다.
Spring JDBC는 기존의 JDBC를 추상화하고 있는 만큼 지금까지 개발자들이 직접 구현해 왔던 위에서 언급한 중복적으로 구현해야만 했던 반복적인 작업들을 프레임워크가 담당하고 있다.

Spring JDBC를 기반으로 퍼시스턴스 계층을 개발할 경우 개발자들이 구현해야 할 부분은 다음의 표와 같이 상당히 단순해진다.

[표] Spring JDBC를 이용할 때 개발자들이 구현해야 할 부분

작업

Spring JDBC

개발자

Connection 관리

O

X

SQL

X

O

Statement 관리

O

X

ResultSet 관리

O

X

Row 데이터 추출

X

O

파라미터 선언

X

O

파라미터 Setting

O

X

트랜잭션 관리

O

X


Spring JDBC를 사용하기 위하여 기존 JDBC를 사용할 때와 비교해 보면 다음의 표와 같다.

[표] JDBC와 Spring JDBC API

JDBC

Spring JDBC

    DriverManager/DataSource

    DataSource

    Statement/PreparedStatement/CallableStatement

    JdbcTemplate/SQLObjects

    ResultSet/RowSet

    POJO List 또는 Map/SQLRwoSet


Spring JDBC에서는 JDBC에서 지원하던 기능들을 위 표의 API를 이용하여 지원하고 있따. 데이터베이스와의 Connection을 관리하기 위하여 DataSource만을 사용하고 있으며, 쿼리를 실행하는 방법으로는 JdbcTemplate과 SQLObjects 두 가지 방식을 지원하고 있다. 또한 JDBC에서 ResultSet과 RowSet으로 반환되던 쿼리결과는 POJO List 또는 Map으로 반환할 수 있다.

# SQL 쿼리 관리 방안
StringBuffer를 사용하지 않고 쿼리가 길어질 경우 가독성을 높이기 위해 Application이 사용하는 쿼리를 MessageSource에서 관리하는 방법을 이용하는 것이 좋다.
MessageSource를 사용할 경우 Application 개발에서 사용하는 모든 쿼리를 한 곳에 모아서 관리할 수 있기 때문에 향후 튜닝 작업을 할 때 유용하게 사용할 수 있을 것으로 생각된다.
일반적으로 Application을 개발하는 개발자와 Database를 담당하고 있는 DBA가 분리되어 있기 때문에 Application 튜닝 작업 시 이 MessageSource 파일을 DBA에게 전달함으로써 Application에서 사용하는 모든 쿼리를 빠른 시간 내에 분석하는 것이 가능하도록 지원할 수 있다.

Spring JDBC 기반 하에서 MessageSource를 이용하도록 하려면 다음과 같이 구현하는 것이 가능하다.

 DBQuery.properties - 사용자 관리 모듈 쿼리

 board.sql.insert = INSERT INTO BOARD \
            (boardno, title, name, email, password, \
            createdate, content) \
          VALUES(?, ?, ?, ?, ?, ?, ?)
 board.sql.update = UPDATE BOARD SET \
      title=?, name=?, email=?, content=? \
       WHERE boardno=?
 board.sql.update.hitcount = UPDATE BOARD SET \
        hitcount = hitcount + 1 \
          WHERE boardno=?
 board.sql.delete = DELETE FROM BOARD WHERE boardno=?
 board.sql.select.byboardno = SELECT \
        title, name, email, password, \
        createdate, content, hitcount \
        FROM BOARD WHERE boardno=?
 board.sql.select.list = SELECT \
       boardno, title, name, email, createdate, hitcount \
      FROM BOARD ORDER BY CREATEDATE DESC LIMIT ?, ?
 board.sql.totalcount = SELECT count(*) FROM BOARD      
 boardfile.sql.insert = INSERT INTO BOARDFILE VALUES(?, ?, ?, ?, ?, ?)
 boardfile.sql.delete.byboardno = DELETE FROM BOARDFILE WHERE boardno=?
 boardfile.sql.delete.byboardfileno = DELETE FROM BOARDFILE WHERE fileno=?
 boardfile.sql.select.byboardfileno = SELECT \
          fileno, filesize, filename, \
          contenttype, tempfilename \
           FROM BOARDFILE WHERE fileno=?
 boardfile.sql.select.byboardno = SELECT \
         fileno, filesize, filename \
         FROM BOARDFILE WHERE boardno=?


 applicationContext.xml

 <beans>
    ... 중간 생략 ...

    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>DBQuery</value>
                <value>Messages</value>
            </list>
        </property>
    </bean>

    <bean id="messageSourceAccessor" class="org.springframework.context.support.MessageSourceAccessor">
        <constructor-arg>
            <ref local="messageSource" />
        </constructor-arg>
    </bean>

    <!--
        absctract 속성이 true로 설정되어 있으면 빈을 직접 생성하여 사용할 수 없으며
        다른 빈들의 부모(parent) 역할을 하는 빈으로 사용된다.
        공통적인 설정 정보가 있는 경우에 유용하게 사용된다.
    -->

    <bean id="myJdbcDaoSupport" abstract="true" class="net.javajigi.common.dao.MyJdbcDaoSupport">
        <property name="dataSource">
            <ref local="dataSource" />
        </property>
        <property name="messageSourceAccessor">
            <ref bean="messageSourceAccessor" />
        </property>
    </bean>

    <!--
        모든 DAO 클래스는 MyJdbcDaoSupport 클래스의 하위 클래스로
        DataSource와 MessageSourceAccessor 인스턴스를 공통적으로 사용하기 위해
        parent 속성을 사용하여 정의한다.
    -->

    <bean id="boardDAOTarget" parent="myJdbcDaoSupport" class="net.javajigi.board.dao.SpringJDBCWithMSBoardDAO">
        <property name="incrementer">
            <ref local="boardIncrementer" />
        </property>
    </bean>

    <bean id="boardFileDAOTarget" parent="myJdbcDaoSupport" class="net.javajigi.board.dao.SpringJDBCWithMSBoardFIleDAO">
        <property name="incrementer">
            <ref local="boardFileIncrementer" />
        </property>
    </bean>
 </beans>



 MySQLUserDAO.java

 package net.javajigi.user.dao;

 ... 중간 생략 ...

 public class MySQLUserDAO extends MyJdbcDaoSupport implements UserDAO {

     ... 중간 생략 ...

    public int insert (User newUser) throws DataAccessException {
        return getJdbcTemplate().update(
                getMessageSourceAccessor().getMessage("userinfo.insert"),
                new Object[] { newUser.getUserId(), newUser.getPassword(), newUser.getName(),
                        newUser.getEmail(), new Boolean(newUser.isAdmin()) });

    }

    public User findUser (String userId) throws DataAccessException (
        UserQuery query = new UserQuery(getDataSource(),
                getMessageSourceAccessor().getMessage("userinfo.select.byuserid"));

        return (User)query.findObject(userId);

    }

    protected class UserQuery extends MappingSqlQuery {
        protected UserQuery (DataSource ds, String findQuery) {
            super(ds, findQuery);
            declareParameter(new SqlParameter(Types.VARCHAR));
        }

        protected Object mapRow (ResultSet rs, int rownum) throws SQLException {
            User user = new User();
            user.setUserId(rs.getString("userId"));
            user.setPassword(rs.getString("password"));
            user.setName(rs.getString("name"));
            user.setEmail(rs.getString("email"));
            user.setAdmin(rs.getBoolean("adminYN"));
        }

    }



# 자료실 게시판 예제 요약

1. MyJdbcDaoSupport
    - 관계형 데이터베이스 기반 하에서 개발되는 모든 퍼시스턴스 계층의 DAO 클래스는 데이터베이스의 Connection 인스턴스가 필요하다.
    - Spring 프레임워크는 모든 DAO 클래스에서 공통적으로 필요한 속성과 기능들을 포함하고 있는 Base 클래스로 org.springframework.jdbc.core.support.JdbcDaoSupport를 지원하고 있다.
    - JdbcDaoSupport 클래스는 DataSource를 관리할 뿐만 아니라 JdbcTemplate 클래스에 접근 가능하도록 지원하고 있다.
    - 해당 프로젝트에서만 공통적으로 필요한 기능이나 속성을 구현하여 개발을 진행할 때 유용하게 사용할 수 있도록 하기 위해서 JdbcDaoSupport 클래스를 상속하는 MyJdbcDaoSupport 클래스를 만들어 사용하는 것이 좋다.

2. BoardDAO, BoardFileDAO
    - JdbcTemplate 기반 : 모든 쿼리를 JdbcTemplate 클래스가 가지고 있는 메소드를 이용하여 실행

Insert, Update, Delete

    int update(String sql)

    int update(String sql, Object[] args)

    int update(String sql, Object[] args, int[] argTypes)

Select

    int queryForInt(String sql)

    int queryForInt(String sql, Object[] args)

    long queryForLong(String sql)

    long queryForLong(String sql, Object[] args)

    Object queryForObject(String sql, Class requiredType)

    Object queryForObject(String sql, Object[] args, RowMapper rowMapper)

    List queryForList(String sql)

    List queryForList(String sql, Object[] args)

    ...


출처 : http://kr.blog.yahoo.com/i056695/1024

[본문링크] Spring 프레임워크 워크북 정리노트 - Chapter4. Spring JDBC
[1]
코멘트(이글의 트랙백 주소:/cafe/tb_receive.php?no=30341
작성자
비밀번호

 

SSISOCommunity

[이전]

Copyright byCopyright ⓒ2005, SSISO Community All Rights Reserved.