[spring] 데이터 액세스층(DAL)

sesame·2021년 8월 4일

Spring

목록 보기
9/12

데이터 액세스층

데이터 액세스층의 역할은 DB의 접속과 SQL 발행 같은 데이터 액세스 처리를 비즈니스 로직층으로부터 분리하는 것이다. 덕분에 비즈니스 로직층은 데이터 액세스 처리에 신경 쓰지 않고 기술할 수 있으므로 소스코드가 확실히 간결해지고 그렇기 때문에 유지관리가 쉬워진다.

DAO pattern(Data Access Object)

데이터 액세스의 처리에 특화된 오브젝트를 일반적으로 DAO라고 한다.
DAO가 구현하는 메소드는 단순한 CRUD를 갖춘 형태가 되고, 클래스는 테이블 별로 만들어지는 일이 많다.
부품화하고자 하는 인터페이스를 준비해 개발 효율이나 유연성을 높인다.

자바 데이터 액세스 기술과 스프링의 기능


스프링 기능을 이용할 때의 장점

  • 데이터 액세스 처리를 간결하게 기술

  • 범용적이고 체계적인 데이터 액세스 예외 처리

  • 스프링의 트랜잭션 기능 이용

🚨 JDBC를 직접 사용했을 때의 문제점

  • 간단한 select문조차 작성 시 소스코드가 길어진다.

  • Connection, PreparedStatement를 얻은 후 연결 해제 처리를 하지 않으면 DB 리소스 고갈이나 메모리 누수의 원인이 되며 최악의 경우 시스템이 정지한다.

  • DB 제품마다 오류코드가 다르므로 SQLException 사용 시 제품이 바뀔 때마다 수정이 필요하다.

  • 예외 처리 시 Catch 구문이 필수로 필요하다.

✨스프링 JDBC 이용 시 해결 가능

  • Template 클래스를 사용하여 소스코드를 단순하게 한다.

    • 스프링 JDBC의 두 개의 클래스 JDBCTemplate 클래스와 NamedParameterJdbcTemplate 클래스가 있는데, 이 둘을 템플릿 클래스라고 부른다. JDBC로 구현했을 때 긴 코드 부분을 단순하게 구현해 주는 것이다.
  • SELECT문 – 도메인으로 변환하지 않을 때

    • (도메인으로 변환하지 않을 때란 예를 들어 레코드의 수를 조회할 때 한 레코드 안의 특정 칼럼처럼 단순한 값을 가져올 때를 가리킨다.)
  • SELECT문 – 도메인으로 변환할 때

  • Insert, Update, Delete문

    • 메소드가 다양했던 SELECT문과 달리 INSERT, UPDATE, DELETE문 모두 update 메서드만 사용한다. 모두 갱신 계통의 SQL이기 때문이다. (메소드명인 update와 SQL의 UPDATE문은 다른 개념)
jdbcTemplate.update( // INSERT문
        "insert into ACCOUNT (ACC_NO, NAME, BALANCE)
                  values (?, ?, ?)"
         , acc.getAccNo( ), acc.getName( ), acc.getBalance( ));
jdbcTemplate.update( // UPDATE문
         "update ACCOUNT set BALANCE=?
         where ACC_NO=?"
         , acc.getBalance( ), acc.getAccNo( ));
jdbcTemplate.update( // DELETE문
         "delete from ACCOUNT
         where ACC_NO=?"
         , acc.getAccNo( ));
  • NamedParameterJdbcTemplate
    • 플레이스홀더를 사용하면 SQL문의 파라미터 값이 많다면 혼란스러워지는데, NamedParameterJdbcTemplate를 사용하면 좋다. 파라미터 순서가 어긋날 위험성을 없앨 수 있다.
npJdbcTemplate.update(
         "insert into ACCOUNT (ACC_NO, NAME, BALANCE)" +
                  " values (:ACC, :NAM, :BAL)"
         , new MapSqlParameterSource( ) // 이름으로 매칭
         .addValue("ACC", acc.getAccNo( )) // 메서드 체인
         .addValue("BAL", acc.getBalance( )) // 반환 값: ↓객체
         .addValue("NAM", acc.getName( )) // MapSqlParameterSource
);
BeanPropertySqlParameterSource bp=new BeanPropertySqlParameterSource(acc);
npJdbcTemplate.update(
         "insert into ACCOUNT (ACC_NO, NAME, BALANCE)" +
                  " values (:accountNo, :name, :balance)"
         , bp);
  • BatchUpdate 메소드
    • 배치 업데이트 메소드는 많은 양의 레코드를 한 번에 갱신하기 위한 메소드이다. update메소드로 한번 한번 해서 여러 번 하는 것과 배치업데이트를 사용함은 성능 차이가 많이 나기 때문에 배치업데이트를 이용하는 것이 좋다.

범용 데이터 액세스 예외

  1. 독자적 예외에 대한 범용적 예외로 변환: 개별적인 데이터 액세스 기술의 독자적 예외를 체계적인 범용 데이터 액세스 예외로 변환한다.

  2. SQLException을 범용 예외로 자동 변환 방법: NamedParameterJdbcTemplate 클래스 사용, DAO 클래스에 @Repository 애너테이션 설정 및 Bean 정의 파일 설정

데이터 소스

데이터 소스는 데이터 소스와 접속 오브젝트 Connection 오브젝트의 팩토리라고 할 수 있다.
커넥션 오브젝트의 생애 주기는 데이터 소스에 맡겨져 있고 일반 업무 애플리케이션에서는 커넥션 풀에 의해 커넥션 오브젝트를 돌려쓰는 구조로 되어있다. 그 이유는 제한 없이 Connection 오브젝트가 만들어져 DB의 리소스가 고갈되는 것을 막거나 커넥션 오브젝트의 생성, 해체 시의 부하를 막기 위해서이다.

스프링에서 데이터 소스를 이용하는 방법

  1. 데이터 소스를 Bean 정의 파일로 정의한다. 개발자가 작성한 Bean과 스프링이 제공하는 Template 클래스에 주입하여 사용한다.

  2. 프로퍼티의 파일 활용하여 context 스키마의 property-placeholder 태그를 이용한다.


스프링이 제공하는 데이터 소스

  • SingleConnectionDataSource

    • 커넥션 하나로 계속 재사용(테스트 커넥션과 애플리케이션 커넥션이 동일)
  • DriverManagerDataSource

    • 커넥션 요청마다 커넥션 객체 생성, 반환
  • 커넥션 풀 지원하지 않음 (실무 용이 아님)

서드파티가 제공하는 데이터 소스

  • DBCP(아파치), c3p0(Machinery for Chane)
    • 커넥션 풀 지원, 오픈 소스

애플리케이션 서버가 제공하는 데이터 소스

  • JNDI를 사용한 데이터 소스 객체 얻기
    • naming service가 관리하는 표준 API

0개의 댓글