작심칠일러의 스프링 시작하기(7)-1

서은경·2022년 8월 9일
0

Spring

목록 보기
11/43

JDBC 프로그래밍의 단점을 보완하는 스프링

JDBC API를 이용하면 DB 연동에 필요한 Connection을 구한 다음 쿼리를 실행하기 위한 PreparedStatement를 생성한다. 그리고 쿼리를 실행한 뒤에는 finally 블록에서 ResultSet, PreparedStatement, Connection을 닫는다.

Member member;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;

try {
	conn = DriverManager.getConnection("~~");
    
    // 핵심코드는 여기서부터
    pstmt = conn.prepareStatement("query ~~");
    pstmt.setString(1, param~~);
    
    ..생략..
    
    // 여기까지 (생략했지만)
} catch(SQLException e) {
	e.printstackTrace();
    throw e;
} finally {
	if(rs != null) {
    }
    ..생략..
    
}

여기서 문제는 핵심코드를 제외한 코드는 사실상 데이터 처리와는 상관없는 코드지만 JDBC 프로그래밍을 할 때 구조즉으로 반복된다.

구조적인 반복을 줄이기 위한 방법은 템플릿 메서드 패턴과 전략 패턴을 함께 사용하는 것이다. 스프링은 바로 이 두 패턴을 엮은 JdbcTemplate 클래스를 제공한다.

템플릿 메서드 패턴 : 어떤 작업을 처리하는 일부분을 서브클래스로 캡슐화해,
전체 일을 수행하는 구조는 바뀌지 않으면서 특정 단계에서 수행하는 내역을 변경함
ex. 

전략 패턴 : 객체들이 할 수 있는 행위 각각에 대해 전략 클래스를 생성하고, 유사한 행위들을 캡슐화하는 인터페이스를 정의하여 
객체의 행위를 동적으로 바꾸고 싶은 경우 행위의 수정 없이 전략만 바꿔 유연하게 확장함
ex.

DB 연동

실습을 위해 gradle 파일에 필요 기능을 임포트한다.


    // JdbcTemplate 등 JDBC 연동에 필요한 기능을 제공한다
    implementation 'org.springframework.boot:spring-boot-starter-jdbc'
    // DB 커넥션풀 기능을 제공한다
    implementation group: 'org.apache.tomcat', name: 'tomcat-jdbc', version: '8.5.32'
    // MySQL 연결에 필요한 JDBC 드라이버를 제공한다
    implementation 'mysql:mysql-connector-java'

DataSource 설정

DataSource 란 DB와 관계된 커넥션 정보를 담고 있으며 빈으로 등록하여 인자를 넘겨준다. 이 과정에서 spring은 DataSource로 DB와의 연결을 획득한다.

스프링이 제공하는 DB 연동 기능은 DataSource를 사용해서 DB Connection을 구한다. DB 연동에 사용할 DataSource를 스프링 빈으로 등록하고 DB 연동 기능을 구현한 빈 객체는 DataSource를 주입받아 사용한다.

Tomcat JDBC 모듈은 javax.sql.DataSource를 구현한 DataSource 클래스를 제공한다.

package config;

import org.apache.tomcat.jdbc.pool.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import spring.MemberDao;


@Configuration
public class AppCtx {

    // close 메서드는 커넥션 풀에 보관된 Connection을 닫음
    @Bean(destroyMethod = "close")
    public DataSource dataSource() {
        // 1.DataSource 객체 생성
        DataSource ds = new DataSource();
        // 2.JDBC 드라이버 클래스 지정(mysql 사용)
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        // 3.JDBC URL 지정, 데이터베이스와 테이블 캐릭터 셋을 UTF-8로 설정했으므로 파라미터를 이용해 연결 시 사용할 캐릭터셋 지정
        ds.setUrl("jdbc:mysql://localhost/spring5fs?characterEncoding=utf8");
        // 4.DB 연결 시 사용할 계정과 암호 지정
        ds.setUsername("spring5");
        ds.setPassword("spring5");
        // 5.커넥션 풀을 초기화할 때 생성할 초기 커넥션 개수 지정(기본값은 10)
        ds.setInitialSize(2);
        // 6.커넥션 풀에서 가져올 수 있는 최대 커넥션 개수 지정(기본값은 100)
        ds.setMaxActive(10);
        return ds;
    }

    @Bean
    public MemberDao memberDao() {
        return new MemberDao(dataSource());
    }
}

Tomcat JDBC의 주요 프로퍼티

  • setInitialSize(int)
    커넥션 풀을 초기화할 때 생성할 초기 커넥션 개수를 지정한다. 기본값은 10이다.
  • setMaxActive(int)
    커넥션 풀에서 가져올 수 있는 최대 커넥션 개수를 지정한다. 기본값은 100이다.
  • setMaxIdle(int)
    커넥션 풀에 유지할 수 있는 최대 커넥션 개수를 지정한다. 기본값은 maxActive와 같다.
  • setMinIdle(int)
    커넥션 풀에 유지할 최소 커넥션 개수를 지정한다. 기본값은 InitialSize에서 가져온다.
  • setMaxWait(int)
    커넥션 풀에서 커넥션을 가져올 때 대기할 최대 시간을 밀리초 단위로 지정한다. 기본값은 30000밀리초(30초)이다.
  • setMaxAge(long)
    최초 커넥션 연결 후 커넥션의 최대 유효 시간을 밀리초 단위로 지정한다. 기본값은 0이다.(=유효시간 없음)
  • setValidationQuery(String)
    커넥션이 유효한지 검사할 때 사용할 쿼리를 지정한다. 언제 검사할지는 별도 설정으로 지정한다. 기본값은 null이다.(=검사 안함) "select 1" 이나 "select 1 from dual"과 같은 쿼리를 주로 사용한다.
  • setValidationQueryTimeout(int)
    검사 쿼리의 최대 실행 시간을 초 단위로 지정한다. 이 시간을 초과하면 검사에 실패한 것으로 간주한다. 0 이하로 지정하면 비활성화한다. 기본값은 -1이다.
  • setTestOnBorrow(boolean)
    풀에서 커넥션을 가져올 때 검사여부를 지정한다. 기본값은 false이다.
  • setTestOnReturn(boolean)
    풀에 커넥션을 반환할 때 검사 여부를 지정한다. 기본값은 false이다.
  • setTestWhileIdle(boolean)
    커넥션이 풀에 유휴 상태로 있는 동안에 검사할지 여부를 지정한다. 기본값은 false이다.
  • setMinEvictableIdleTimeMillis(int)
    커넥션 풀에 유휴 상태로 유지할 최소 시간을 밀리초 단위로 지정한다. testWhileIdle이 true이면 유휴 시간이 이 값을 초과한 커넥션을 풀에서 제거한다. 기본값은 60000밀리초(60초)이다.
  • setTimeBetweenEvictionRunsMillis(int)
    커넥션 풀의 유휴 커넥션을 검사할 주기를 밀리초 단위로 지정한다. 기본값은 50000밀리초(50초)이다. 이 값을 1초 이하로 설정하면 안된다.

커넥션 풀은 커넥션을 생성하고 유지한다. 커넥션 풀에 커넥션을 요청하면 해당 커넥션은 활성(active) 상태가 되고, 커넥션을 다시 커넥션 풀에 반환하면 유휴(idle) 상태가 된다.

🙋‍♀️ 커넥션 풀이 뭔가요?
💡 커넥션 풀은 일정 개수의 DB 커넥션을 미리 만들어두는 기법이다.
최초 연결에 따른 응답 속도 저하와 동시 접속자가 많을 때 발생하는 부하를 줄이기 위해 사용하는 것이다.

0개의 댓글