backend/Spring

[Spring] Hitting the database

버리야 2007. 11. 4. 20:56
반응형

* Hitting the database


1) Spring의 DataAccessException

java.sql.SQLException은 checked Exception입니다. 즉, 개발자가 try-catch로 잡아줘야 합니다.

이는 코드를 난잡하게 만들수 있습니다.  그리고 SQLException이 제공하는 예외는 Spring에 비해서 매우 종류가 많지 않습니다.

 
DataAccessException은 SQLException이나 HibernateException등과 같이 특정 기술에 의존적인 예외를 던지지 않기때문에, 데이터 접근 인터페이스가 구현에 의존적인 예외가 아닌 스프링의 일반적인 DataAccessException을 던지게 함으로써, 특정한 퍼시스턴스 구현에 결합되는 일을 방지합니다.

 
DataAccessException은 RuntimeException이기 때문에 unchecked Exception에 속하기 때문에 개발자가 반드시 처리하지 않아도 됩니다. unchecked Exception이 발생하는 경우는 대개 복구가 불가능한 것이기 때문에 개발자가 직접 처리해야 할 필요는 없습니다. 만약 복구가 가능한 것이라면 예외를 잡아 호출 스택으로 전달되도록 할 수도 있습니다. (처리하고 싶으면 잡아서 처리하고, 하고 싶지 않으면 Spring에서 잡도록 내버려 둬도 됩니다.)

 
Spring의 DAO Exception 분류 체계는 매우 세밀하기 때문에, 서비스 객체가 잡고자 하는 exception의 타입과 호출 스택에 전달하고자 하는 exception을 정확히 선택할 수 있습니다.


2) Spring에서 데이터 접근

Spring은 데이터 접근 프로세스에 있어서 고정된(변하지 않는) 부분을 template(템플릿)으로 가변적인(변하는) 부분을 callback(콜백)으로 구분합니다.

template은 프로세스의 고정된 부분을 관리하는 반면, callback은 구체적인 구현을 넣어야 하는 장소입니다.

 
template은 데이터 저장소로의 연결 취득, 트랜잭션 제어, 자원반환, 예외 처리등하고싶을 일을 구현하기 위해 중복적으로 해야하는 작업들입니다.


callback 인터페이스의 구현 클래스는 질의문 생성, 파라미터 바인딩, 결과 집합 마샬링(marshalling) 등 애플리케이션에 특정적인 부분을 정의합니다.


  

[그림] 스프링 DAO 템플릿과 콜백 클래스의 역할 ( 차후에 추가 )


* JDBC 코드의 문제점은 무엇일까요? (Quiz)


Spring에서의 JdbcTemplate

Spring이 JDBC 프레임워크는 자원 관리와 에러 처리의 부담을 떠맡음으로써 JDBC 코드를 깨끗하게 만들어 줍니다.

 
JdbcTemplate 클래스가 작업하기 위해 필요한 것은 DataSource뿐입니다.


- JdbcTemplate과 함께 쓰이는 Class

//---------------------------------------------------------------
// 데이터 쓰기
//---------------------------------------------------------------

  • PreparedStatementCreator : 이 인터페이스의 구현 클래스는 PreparedStatement를 생성시킬 책임을 갖는다.  이 인터페이스를 구현할 때에는 인자로 넘어온 Connection으로부터 PreparedStatement를 생성하고 리턴해줘야 한다. 그러나 예외 처리에 대해서는 신경쓰지 않아도 된다.

    /**
     * One of the two central callback interfaces used by the JdbcTemplate class.
     * This interface creates a PreparedStatement given a connection, provided
     * by the JdbcTemplate class. Implementations are responsible for providing
     * SQL and any necessary parameters.
     */
    public interface PreparedStatementCreator {


        /**
         * Create a statement in this connection. Allows implementations to use
         * PreparedStatements. The JdbcTemplate will close the created statement.
         * @param con Connection to use to create statement
         * @return a prepared statement
         * @throws SQLException there is no need to catch SQLExceptions
         * that may be thrown in the implementation of this method.
         * The JdbcTemplate class will handle them.
         */
        PreparedStatement createPreparedStatement(Connection con) throws SQLException;

    }

  • SqlProvider : SqlProvider 인터페이스의 getSql() 이라는 하나의 메소드를 구현함으로써 클래스가 SQL 문자열을 JdbcTemplate 클래스에 제공할 수 있게 된다. 이렇게 하면  JdbcTemplate 클래스가 자신이 실행하는 모든 SQL 문장에 대해 로그를 남기는 것이 가능해진다.

    public interface SqlProvider {

        /**
         * Return the SQL string for this object, i.e.
         * typically the SQL used for creating statements.
         * @return the SQL string, or <code>null</code>
         */
        String getSql();

    }


  • PreparedStatementSetter : PreparedStatementCreatr를 보완. 파라미터를 세팅하기만 하고 모든 예외 처리는 JdbcTemplate 클래스가 해 줄 것이다.

    public interface PreparedStatementSetter {

        /**
         * Set parameter values on the given PreparedStatement.
         * @param ps the PreparedStatement to invoke setter methods on
         * @throws SQLException if a SQLException is encountered
         * (i.e. there is no need to catch SQLException)
         */
        void setValues(PreparedStatement ps) throws SQLException;

    }


  • BatchPreparedStatement : 갱신하고자 하는 레코드가 둘 이상일 경우.

    public interface BatchPreparedStatementSetter {

        /**
         * Set parameter values on the given PreparedStatement.
         * @param ps the PreparedStatement to invoke setter methods on
         * @param i index of the statement we're issuing in the batch, starting from 0
         * @throws SQLException if a SQLException is encountered
         * (i.e. there is no need to catch SQLException)
         */
        void setValues(PreparedStatement ps, int i) throws SQLException;

        /**
         * Return the size of the batch.
         * @return the number of statements in the batch
         */
        int getBatchSize();

    }


    // ------------------------------------------------------------------------------------
    //  데이터 읽기
    // ------------------------------------------------------------------------------------


    스프링을 사용하지 않은 이전의 JDBC 에서는 데이터베이스에 질의를 한 후에 ResultSet을 순환하여
    결과를 얻어내야 하는데 스프링은 그 일을 대신 해 준다.

  • RowCallbackHandler

  • RowMapperResultReader -> 2.x 버젼부터 RowMapperResultSetExtractor 사용

  • CallableStatementCallback : 저장 프로시저 호출하기


3) DaoSupport

DaoSupport class사용시의 문제점

MemberDaoImpl, PostDaoImpl, BoardDaoImpl 등의 class가 있다고 하면 JdbcTemplate을 이용하여 구현을 하려고 하면


JdbcTemplate을 설정하는 코드가 각각의 클래스의 Setter 메소드를 이용하여 세팅이 되야하는데, 이것을 중복을 유발합니다.


DAO 클래스마다 중복적으로 발생하는 JdbcTemplate설정을 추상화 계층으로 끌어올려 JdbcDaoSupport Class를 만들어서, Support 클래스는 데이터베이스와의 통신에 사용되는 클래스에 직접적으로 접근할 수 있도록 해줍니다.


JdbcDaoSupport클래스는 Connection 객체를 얻기 위해 getConnection() 메소드를 호출하면 됩니다.


JdbcDaoSupport 클래스를 이용하면 DataSource를 Spring 설정파일에서 매핑시켜주지 않아도 됩니다.


4) Spring의 ORM 프레임워크 지원 기능

  •  lazy loading : 객체들의 관계 전체를 그대로 얻기 원하지 않을 경우 필요로 하는 데이터만 가져올 수 있도록 해줌
  • eager fetching : ( <-> lazy loading) : 하나의 질의로 전체 객체들을 한번에 얻어오는 것
  • caching : 주로 읽기만 하는 데이터의 경우 매번 Database에서 가져오기를 원치 않을 때 사용.
  • cascading : 제약사항

5) Hibernate와의 연동

Hibernate에서는 SessionFactory를 이용하여 session객체를 생성하는 것이 가장 중요하고,

설정파일에서 SessionFactory를 property로 추가(DataSource)합니다.


6) Caching

Cache 설정파일을 만들고, Spring 설정파일에서 cache 설정파일이 어디있는지 설정해주고,

cache대상과 비울 대상을 메소드로 설정합니다.(XML이나 Annotation으로 설정)








반응형