자바에서는 JDBC API를 사용하거나 JPA, MaBatis 같은 기술을 이용해 DB 연동을 처리한다. 스프링에서는 JDBC 프로그래밍의 단점을 보완하여 코드의 중복을 줄여주며, 트랜잭션 관리도 쉽다. 스프링에서 JDBC를 이용해 DB 연동을 처리하는 방법을 알아보자.
JDBC 프로그래밍과 스프링
JDBC 프로그래밍을 하다 보면 데이터를 처리하는 핵심적인 기능을 위한 코드보다 DB 연동에 필요한 설정들을 위한 코드가 훨씬 많아지기 일쑤다. DB 연동에 필요한 Connection을 구해서 쿼리를 실행하기 위한 PreparedStatement를 생성하고, 쿼리를 실행한 뒤에는 ResultSet, PreparedStatement, Connection을 닫아주는 코드 등이 반복된다.
구조적인 반복을 줄이기 위한 방법은 템플릿 메서드 패턴과 전략 패턴을 함께 사용하는 것인데, 스프링은 이 두 패턴을 엮은 JdbcTemplate 클래스를 제공한다. JdbcTemplate 클래스를 사용하면 반복되는 코드를 줄일 수 있다.
또한 스프링에서는 트랜잭션 관리가 쉽다. JDBC API를 사용하면 수동으로 commit()과 rollback() 메서드를 이용해서 트랜잭션을 커밋하거나 롤백해야 한다. 스프링에서는 트랜잭션을 적용하고 싶은 메서드에 @Transactional 애노테이션을 붙이기만 하면 커밋과 롤백 처리는 스프링이 알아서 처리한다.
DB 연동을 위한 스프링 프로젝트 설정
JDBC 연동을 위해 아래의 모듈을 pom.xml 파일에 새로 추가해야 한다.
spring-jdbc
tomcat-jdbc
mariadb-java-client
spring-jdbc 모듈은 JdbcTemplate 등 JDBC 연동에 필요한 기능을 제공하며, tomcat-jdbc는 DB 커넥션 풀 기능을 제공한다. 커넥션 풀은 일정 개수의 DB 커넥션을 미리 만들어놓아서 최초 연결에 따른 응답 속도 저하와 동접자수가 많을 때 발생하는 부하를 줄여주기 위해 사용하는 기법이다.
MariaDB를 연동하는 방법은 아래의 포스트에서 자세히 설명하였다.
DataSource 설정하기
스프링에서는 DataSource를 사용해서 DB Connection을 구한다. DB 연동에 사용할 DataSource를 스프링 빈으로 등록하고 DB 연동 기능을 구현한 빈 객체는 DataSource를 주입받아서 사용한다. 아래는 설정 클래스에서 DataSource를 스프링 빈으로 등록하는 예제이다.
@Configuration
public class AppCtx {
// close() 메서드를 통해 커넥션풀에 보관된 Connection을 닫도록 설정
@Bean(destroyMethod = "close")
public DataSource dataSource() {
DataSource ds = new DataSource();
// MariaDB 드라이버 클래스를 사용하여 JDBC 드라이버 클래스 지정
ds.setDriverClassName("org.mariadb.jdbc.Driver");
// JDBC URL 지정 - 캐릭터셋을 utf8로 지정
ds.setUrl("jdbc:mariadb://localhost:3306/DbName?characterEncoding=utf8");
// DB에 연결할 때 사용할 사용자 계정과 암호 지정
ds.setUsername("dctWonjung");
ds.setPassword("dctWonjung");
// 커넥션 풀을 초기화할 때 생성할 초기 커넨션 개수 지정 (default: 10)
ds.setInitialSize(2);
// 커넥션 풀에서 가져올 수 있는 최대 커넥션 개수 지정 (default: 100)
ds.setMaxActive(10);
// 커넥션이 풀에 유휴 상태로 있는 동안에 검사할지 여부를 지정 (default: false)
ds.setTestWhileIdle(true);
// 커넥션 풀에 유휴 상태로 유지할 최소 시간을 밀리초 단위로 지정
// testWhileIdle 설정이 true라면, 이 시간을 초과한 커넥션을 풀에서 제거 (default: 60000)
ds.setMinEvictableIdleTimeMillis(60000 * 3);
// 커넥션 풀의 유휴 커넥션을 검사할 주기를 밀리초 단위로 지정 (default: 5000)
ds.setTimeBetweenEvictionRunsMillis(10 * 1000);
return ds;
}
}
커넥션 풀은 커넥션을 생성하고 유지한다. 커넥션 풀에 커넥션을 요청하면 해당 커넥션은 active(활성) 상태가 되고, 커넥션을 다시 풀에 반환하면 idle(유휴) 상태가 된다. DataSource#getConnection() 메서드를 실행하면 커넥션을 커넥션 풀에서 가져와서 커넥션이 활성 상태가 되고, 커넥션을 종료(close)하면 커넥션이 풀로 돌아가서 유휴 상태가 되는 것이다.
커넥션 풀은 성능 때문에 사용한다. 매번 새로운 커넥션을 생성하면 그때마다 연결 시간이 소모되는데, 커넥션 풀을 사용하면 커넥션을 미리 만들어놨다가 필요할 때 꺼내서 사용하므로 연결 시간이 줄어들어서 전체 응답 시간도 짧아진다. 따라서 최소 수준의 커넥션을 미리 생성하는 것이 좋다. (initialSize 설정)
커넥션 풀에 생성된 커넥션은 지속적으로 재사용되지만 커넥션이 영원히 유지되는 것은 아니다. DBMS 설정에 따라 일정 시간 내에 쿼리를 실행하지 않으면 연결을 끊기도 한다. 그런데 DBMS에서 연결을 끊어도 커넥션이 풀에 남아있기 때문에 이 커넥션을 가져다가 사용하면 익셉션이 발생한다.
따라서 이런 문제를 방지하기 위해 커넥션 풀의 커넥션이 유효한지 주기적으로 검사를 해야 한다. (TestWhileIdle, MinEvictableIdleTimeMillis, TimeBetweenEvictionRunsMillis 설정)
DataSource 클래스의 프로퍼티 설정에 대한 자세한 설명은 아래 포스트를 참고하면 된다.
이번 포스트에서는 스프링에서 DB 연동을 위해 어떤 설정들을 해야 하는지 알아보았다. 다음 포스트에서는 JdbcTemplate 클래스를 이용해서 MariaDB와 실제로 통신하는 방법에 대해 알아보겠다.
참고 서적: <초보 웹 개발자를 위한 스프링 5 프로그래밍 입문>
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
Spring Framework 시리즈
- 스프링 프로젝트 시작하기 (Maven)
- 스프링 컨테이너(Container) 의미
- Dependency, DI, Assembler (의존, 의존 주입, 주입기) 개념 정리
- 스프링에서의 의존 주입(DI)의 의미와 사용법
- 스프링 애노테이션을 사용한 의존 주입(DI)
- 의존 자동 주입(1) - @Autowired 애노테이션
- 의존 자동 주입(2) - 빈 이름과 한정사
- 의존 자동 주입(3) - @Autowired의 필수 여부, 자동 주입과 명시적 의존 주입
- 컴포넌트 스캔 - @Component, @ComponentScan 사용하기
- 빈 객체의 라이프사이클과 범위 (Life Cycle & Scope of Bean)
- AOP 프로그래밍(1) - 프록시와 AOP
- AOP 프로그래밍(2) - 스프링에서의 AOP
- AOP 프로그래밍(3) - 스프링에서의 프록시 생성 방식
'Java > [스프링 5 프로그래밍 입문]' 카테고리의 다른 글
[Spring] DB 연동(2) - JdbcTemplate과 쿼리 (0) | 2021.09.13 |
---|---|
[Spring] Tomcat JDBC DataSource 클래스의 주요 설정(프로퍼티) (0) | 2021.09.10 |
[Spring] AOP 프로그래밍(3) - 스프링에서의 프록시 생성 방식 (0) | 2021.09.01 |
[Spring] AOP 프로그래밍(2) - 스프링에서의 AOP (0) | 2021.08.12 |
[Spring] AOP 프로그래밍(1) - 프록시와 AOP (0) | 2021.08.10 |
댓글