Spring - DB연동(Oracle)

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

일반적인 JDBC 프로그래밍에서는 DriverManager, Connection, Statement, ResultSet 또는 이 연결들을 닫는 close 메서드 부분 등 반복되는 부분이 코드의 절반 이상이였다. 코드의 중복과 반복은 코드의 가독성을 굉장히 떨어뜨린다.

그래서 스프링에서는 JdbcTemplate 클래스를 제공한다. 해당 클래스를 사용하면 코드의 구조적인 중복이 줄고 트랙잭션 관리가 쉽다.

프로젝트 생성


pom.xml에 해당 모듈들을 추가하였다.

  • spring-jdbc : JdbcTemplate 등 JDBC 연동에 필요한 기능을 제공한다.
  • tomcat-jdbc : DB 커넥션풀 기능을 제공한다.
  • logback-classic, slf4j-api : 로그를 보여준다.

"커넥션 풀"
일정 개수의 DB 커넥션을 미리 만들어두는 기법이다. 컨넥션을 미리 생성해두기 때문에 커넥션을 사용하는 시점에서 커넥션을 생성하는 시간을 아낄 수 있다.

DataSource 설정

JDBC API는 DriverManager 외에 DataSource를 이용하여 DB 연결을 구하는 방법을 정의하고 있다.

스프링이 제공하는 DB 연동 기능은 DataSource를 사용해서 DB Connection을 구한다.

@Bean(destroyMethod = "close")
public DataSource dataSource() {
		DataSource ds = new DataSource();
		
        ds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
        // driverClassName 설정
		ds.setUrl("jdbc:oracle:thin:@localhost:1521/xe");
        // Url 설정
		ds.setUsername("아이디");
        // UserID
		ds.setPassword("비밀번호");
        // UserPassword
		ds.setInitialSize(2); // 초기 커넥션 개수
		ds.setMaxActive(10); // 최대 커넥션 개수
		ds.setMaxIdle(10); // 유지할 수 있는 최대 커넥션 개수
		return ds;
}

Tomcat JDBC의 주요 프로퍼티

커넥션 풀에 대한 여러가지 설정이 있다.

  • setInitialSize(int)
    커넥션 풀을 초기화할 때 생성할 초기 커넥션 개수를 지정한다.

  • setMaxActive(int)
    커넥션 풀에서 가져올 수 있는 최대 커넥션 개수 지정(default: 100)

  • setMaxIdle(int)
    커넥션 풀에 유지할 수 있는 최대 커넥션 개수 지정(default: 100)

  • setMinIdle(int)
    :커넥션 풀에 유지할 최소 커넥션 개수 지정(default: initialSize값)

  • setMaxWait(int)
    커넥션 풀에서 커넥션을 가져올 때 대기할 최대 시간을 밀리초 단위로 지정(default: 30000밀리초(30초))

  • setMaxAge(long)
    최초 커넥션 연결 후 커넥션의 최대 유효 시간을 밀리초 단위로 지정(default: 0(유효시간 없음))

  • setValidationQuery(String)
    커넥션이 유효한지 검사할 때 사용할 쿼리를 지정(default: null(검사 안함))

  • setValidationQueryTimeout(int)
    검사 쿼리의 최대 실행 시간을 초 단위로 지정해당 시간을 초과하면 검사에 실패한 것으로 간주0 이하로 지정하면 비활성화(default: -1)

  • setTestOnBorrow(boolean)
    풀에서 커넥션을 가져올 때 검사 여부를 지정(default: false)

  • setTestOnReturn(boolean)
    풀에 커넥션을 반환할 때 검사 여부를 지정(default: false)

  • setTestWhileIdle(boolean)
    커넥션이 풀에 유휴 상태로 있는 동안에 검사할지 여부를 지정(default: false)

  • setMinEvictableIdleTimeMillis(int)
    커넥션 풀에 유휴 상태로 유지할 최소 시간을 밀리초 단위로 지정.testWhileIdle 설정이 true라면, 이 시간을 초과한 커넥션을 풀에서 제거(default: 60000밀리초(60초))

  • setTimeBetweenEvictionRunsMillis(int)
    커넥션 풀의 유휴 커넥션을 검사할 주기를 밀리초 단위로 지정1초 이하로 설정하면 안됨(default: 5000밀리초(5초))

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

JdbcTemplate을 이용한 쿼리 실행

스프링을 사용하면 DataSource나 Connection, Statemement, ResultSet을 직접 사용하지 않고 JdbcTemplate을 이용하서 편리하게 쿼리를 실행할 수 있다.

SELECT 쿼리 실행을 위한 query() 메서드

List<T> query(String sql, RowMapper<T> rowMapper)
List<T> query(String sql, Object[] args, RowMapper<T> rowMapper)
List<T> query(String sql, RowMapper<T> rowMapper, Object... args)

query()메서드는 sql 파라미터로 전달받은 쿼리를 실행하고 RowMapper를 이용해서 ResultSet의 결과를 자바 객체로 변환한다.

<예시코드>

public Member selectByEmail(String email) {
		List<Member> results = jdbcTemplate.query(selectByEmail_sql,
				new RowMapper<Member>() {
			@Override
			public Member mapRow(ResultSet rs, int rowNum) throws SQLException {
				
				Member member = new Member(
						rs.getString("EMAIL"),
						rs.getString("PASSWORD"),
						rs.getString("NAME"),
						rs.getDate("REGDATE"));
				member.setId(rs.getLong("ID"));
				
				return member;
			}
		}, email); // query()함수의 마지막 인자는 가변인자 설정이다.
		
		return results.isEmpty() ? null : results.get(0);
		// 결과가 비어있을 수도 있기에 비어있으면 null을 반환
	}

결과가 1행인 경우 사용할 수 있는 queryForObject메서드

count(*) 쿼리와 같이 실행결과가 한 행 뿐인 쿼리는 List로 받기 보다는 정수 타입으로 받는 것이 옳다. 이를 위한 메서드가 queryForObject()이다.

INSERT, UPDATE, DELETE쿼리를 위한 update() 메서드

INSERT, UPDATE, DELETE 쿼리를 사용하기 위해서는 update()메서드를 이용해야한다.
<예제 코드>

public void update(Member member) {
		jdbcTemplate.update(update_sql,
				member.getName(), member.getPassword(), member.getEmail());
}

위의 코드를 모변 첫번째 인자로는 SQL 쿼리문이 들어가고 그 뒤로는 순서대로 가변인자가 들어간다.

0개의 댓글