DAO/DTO를 구현해보자!

Seculoper·2021년 2월 13일
0

이번 편에서는 직접 구현을 해보는 시간이다.
우선 어떻게 구현할 것인지 구조도를 클래스 다이어그램으로 먼저 살펴보자.


0. 구조도

구조도는 다음과 같다.

  • UserDto
    : DB 데이터를 담기 위한 객체이다.
    POJO하게 작성하는 것이 원칙이다.

  • UserDao
    : Spring JDBC와 동일하다.
    Named와 Simple 템플릿을 이용하여 각종 CRUD 메소드를 구현하였다.

  • DaoSqls
    : Dao 객체의 간결화를 위해 쿼리문들만 따로 분리하였다.
    static으로 구현하였으므로, 바로 사용 가능하다.

  • DBConfig
    : DB와 관련된 설정을 하는 클래스이다.
    단일 책임의 원칙에 따라, Dao에서 분리하였다.
    DB 관련 추가 설정은 여기다 작성하면 된다.

  • ApplicationConfig
    : ROOT Context의 설정 Class이다.
    web.xml의 간결함을 위해, 모든 ROOT Context를 여기에 import하고 해당 클래스만 context 등록하도록 하였다.


1. 각 클래스 작성

그럼 이제 본격적으로 작성해보자.

1. DBConfig

우선은 DataSource가 먼저 필요하므로, DBConfig부터 작성한다.
대략적인 틀을 작성해보면, 이러하다.

@Configuration
@ComponentScan(basePackages = {"DTO", "DAO"})
@EnableTransactionManagement
public class DBConfig {

    @Bean
    public DataSource dataSource() {
    }
}
  • @Configuration
    : 해당 클래스는 설정 Class이므로, 당연히 붙여줘야 한다.

  • @ComponentScan
    : 설정 클래스는 컴포넌트 객체들을 찾아 Bean 등록하는 기능이 있다.
    여기서는 관련된 패키지인 Dao와 Dto를 스캔한다.

  • @TransactionManagement
    : 트랜잭션 기능 사용을 가능하게 한다.
    여기선 사용하지 않은 것이나, 반드시 필요한 기능이니 꼭 추가를 하자!

추가로 DataSource를 @Bean 등록한 것은 Dao의 DI를 구현하기 위한 것임은 다들 알 것이다.

그리고 dataSource 메소드는 이전 JDBC 때와 동일하게 작성하면 된다.

@Configuration
@ComponentScan(basePackages = {"DTO", "DAO"})
@EnableTransactionManagement
public class DBConfig {
    private String driverClassName = "com.mysql.cj.Driver";
    private String dbUrl = "jdbc:mysql://localhost:3306/testdb";
    private String userName = "test";
    private String password = "test";

    @Bean
    public DataSource dataSource() {
        BasicDataSource db = new BasicDataSource();
        db.setDriverClassName(driverClassName);
        db.setUrl(dbUrl);
        db.setUsername(userName);
        db.setPassword(password);

        return db;
    }
}

DBConfig 클래스 완성!


2. DaoSqls

사용할 쿼리문을 모아두는 클래스이다.
(더이상의 말은 생략한다.)

public class DaoSqls {
    // Select 관련
    public static final String SELECT_All = "SELECT * FROM user";
    public static final String SELECT_BY_ID = "SELECT * FROM user WHERE id := userId";

    // Update 관련
    public static final String UPDATE = "UPDATE user SET name := username WHERE id := userId";

    // DELETE 관련
    public static final String DELETE = "DELETE * FROM user WHERE id := userId";
}

3. Dao

이것은 정말 JDBC와 동일해서 설명할 것이 없다.
다만 필자는 여러개의 값을 Insert/Update하는 메소드를 추가하였는데,
이에 관해 잠시 설명하도록 하겠다.

  • BatchUpdate?
    : JDBC 2.0부터 추가되었으며, 여러개의 작업을 간편하게 처리할 수 있는 기능이다.

    이게 무슨 소리인가 하면, 만약 Insert를 3번 하고싶다고 하자.
    원래라면 Insert() 메소드를 3번돌려야 하지만, 이것은 심각한 코드 낭비로 보기 좋지않다.
    하지만 batchUpdate()를 이용하면 한줄로 간편하게 3번을 실행할 수 있다.

    트랜잭션으로 인해 개별로 수행했어야 할 일련의 작업들을 한번의 코드로 처리할 수 있도록 하는 것!
    그것이 바로 batchUpdate()이다!!

    이것이 SimpleInsert는 excuteBatch(),
    namedTemplate는 batchUpdate()
    로 대응된다.

그럼 이제 여러개의 값들을 Insert하는 메소드를 작성해보자.
(Update도 동일하니, 그대로 작성하면 된다.)

// 다수의 유저 insert 가능
    public int[] insertUserList(List<UserDto> userList) {
        // createBatch를 사용하여 SqlParameterSource 배열을 만듦
        SqlParameterSource[] paramList = SqlParameterSourceUtils.createBatch(userList.toArray());
        return simpleInsert.executeBatch(paramList);
    }
  • executeBatch()
    : 해당 메소드의 파라미터Map과 Source[] 타입이 가능하다.
    하지만 Map은 foreach로 일일히 put해줘야 하기 때문에,
    훨씬 간결한 ~~Source[ ]를 사용하였다.

  • createBatch()
    : 말 그대로 batch하기 위한 작업들을 생성해낸다.
    반환 타입도 ~~Source[ ]로, 최적의 메소드라고 할 수 있다.


4. 결론

이것으로 DAO/DTO에 대해 끝마치도록 하겠다.

UserDto는 클래스 다이어그램 대로만 작성하면 되고,
Dao의 나머지 부분은 JDBC와 동일하니, 복습하는 셈치고 작성해보자.

다음은 한층 업그레이드 된, JPA를 시작해보도록 하겠다!
(JPA는 다룰 내용이 정말 많은데, 언제 정리하지..ㅇㅁㅇ)

그럼 모두들 화이팅! : )

위 내용의 전체 소스코드는 아래를 참조하자
>>DAO/DTO 소스코드 완성본

profile
보안이 취미인 개발자(수학자)입니다.

0개의 댓글