본문 바로가기

아는 만큼 보인다/Spring Framework

JdbcTemplate (쓰기 편한 database 접속 api)

스프링이 제공해주는 템플릿/콜백 패턴의 라이브러리(?)이다.

즉, 변하지 않는 부분을 템플릿으로 미리 만들어주었다.

우리가 사용할 때는 변하는 부분(콜백)만 템플릿 메소드에게 파라미터로 전달해주면 끝이다.


사용예)

...

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

jdbcTemplate.update("delete from users");

jdbcTemplate.update(

"insert into users(id, name, password) values(?,?,?)", 

user.getId(), 

user.getName(), 

user.getPassword());

int count = jdbcTemplate.queryForInt("select count(*) from users");

User user = jdbcTemplate.queryForObject(

"select * from users where id=?", 

new Object[] {id}, 

new RowMapper<User>() {

@Override

public User mapRow(ResultSet rs, int rowNum)

throws SQLException {

User user = new User(

rs.getString("id"),

rs.getString("name"),

rs.getString("password"));

return user;

}

});


추가 설명)

JdbcTemplaate 이 다 알아서 해주는 것들?

1. 고정부(변하지 않는 부분) 작업 흐름 지원

DB접속에 사용되는 resource들( Connection, ResultSet .. )을 생성하고..
사용후에는 반환(close)해주고.. 
이런 과정에서 발생할 만한 Exception들을 처리해준다.(try/catch/finally) 

JdbcTemplate의 메소드를 사용하면 이런 것들은 신경쓰지 않아도 되는 것이다.

단, Statement 생성은 고정부가 아닌 변경부이기 때문에..
JdbcTemplate 메소드 사용시 파라미터로 해당 콜백을 만들어 전달해줘야하지만..
이마저도 JdbcTemplate의 내부 콜백이 대신해준다.
그래서 Statement생성에 필요한 sql문만 String으로 전달해줘도 된다.


2. RuntimeException으로의 전환

예외가 발생하는 경우, RuntimeException으로 전환하여 throw 한다. 
기존 SQLException은 check 예외의 일종으로 try/catch를 강제화했지만, 
RuntimeException으로 전환된 예외는 uncheck 예외가 되어 프로젝트 성격에 맞게 필요에 따라 try/catch해주면 된다


3. Transaction 동기화를 알아서 한다.

템플릿 메소드에서
트랜잭션동기화 작업용 저장소에 이미 생성되어 있는 커넥션이 없는 경우에만,
스스로 Connection을 생성하고, 반환(close)한다.

저장소에 생성된 커넥션이 있다면..
외부에서 트랜젝션 처리(커밋/롤백)를 할 수 있도록 저장소에 있는 커넥션을 사용하고 사용후에도 close 하지 않는다.

외부에서 트랜젝션 처리(커밋/롤백)를 하는 예제는 아래와 같다.

...

TransactionSynchronizationManager.initSynchronization(); //트랜잭션 동기화 관리자를 이용해
                                                                                    //동기화 작업을 초기화한다.

Connection c = DataSourceUtils.getConnection(dataSource); //커넥션을 생성하고, 
 //트랜잭션 동기화에 사용될 수 있도록 생성된  커넥션을 저장소에 바인딩한다.

c.setAutoCommit(false); //트랜잭션을 시작한다.


try {

// .. 트랜잭션이 필요한 작업들..

c.commit(); // 정상적으로 작업을 마치면, 트랜잭션을 커밋한다.

} catch(Exception e) {

c.rollback(); // 예외가 발생하면 롤백한다.

throw e;

} finally {

DataSourceUtils.releaseConnection(c, dataSource); // 스프링 유틸리티를 이용해 DB커넥션을 닫는다.

TransactionSynchronizationManager.unbindResource(dataSource); // 동기화 작업을 종료하고

TransactionSynchronizationManager.clearSynchronization();     // 정리한다.

}