1. JdbcDaoSupport 클래스란?
2. JdbcDaoSupport 를 활용한 DB연결 과정
3. 마무리
Spring에서 Database에 접근해 데이터를 가져오는 방법은 크게 4가지가 있다.
Spring 공식 홈페이지에서 제공하는 api를 통해서 jdbcDaoSupport를 검색해 보면 위와 같은 정보를 확인해 볼 수 있다. 우선 jdbcDaoSupport는 추상 클래스로 DaoSupport 클래스를 상속받은 서브클래스임을 알 수 있다.
| 이름 | 설명 |
|---|---|
| createJdbcTemplate(DataSource dataSource) | 주어진 DataSource에 대한 JdbcTemplate을 생성 |
| getJdbcTemplate() |
DataSource로 미리 초기화되거나 명시적으로 설정된 이 DAO에 대한 JdbcTemplate을 반환 Getter Method |
| getDataSource()) |
이 DAO에서 사용하는 JDBC DataSource를 반환 Getter method |
| setDataSource(DataSource dataSource) |
이 DAO에서 사용할 JDBC DataSource를 설정합니다. Setter method |
(출처 : https://mr-popo.tistory.com/101)
DataSource 인터페이스는 커넥션을 획득하는 방법을 추상화 한 인터페이스이며 Java에서 제공하는 표준 인터페이스(javax.sql.DataSource)이다. DataSource 인터페이스의 핵심 기능은 커넥션 조회밖에 없다.JdbcDaoSupport 클래스를 사용해서 DB를 연결하는 방법에는 크게 2가지가 있다. 하나는 XML을 통해서 DB의 설정을 하는 방법이고 나머지는 Class에 DB의 설정을 하고 annotation으로 연결하는 방법이다. 블로그에는 annotation을 활용해서 연결하는 과정을 기록하고자 한다.
//DB를 세팅하는 Class
package pack;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.stereotype.Component;
@Component
public class DataSource extends DriverManagerDataSource{
public DataSource() {
//mariadb-java-client 에서 제공하는 클래스
setDriverClassName("org.mariadb.jdbc.Driver");
setUrl("jdbc:mariadb://localhost:3306/테이블명");
setUsername("유저아이디");
setPassword("비밀번호");
}
}
별개의 클래스에 DB의 세팅을 위와 같이 할 수 있다. 이 때에 주의해서 봐야하는 부분은 DriverManagerDataSource 클래스 를 상속받는다는 것이다.
DriverManagerDataSource 클래스는 Spring Framework에서 제공하는 표준 JDBC DataSource인터페이스를 간단히 구현하는 클래스이다. 그런데 해당 클래스의 설명에서 주목해야하는 부분이 있다. 바로 그것은 해당 클래스는 실제 연결 풀링을 하지 않는다는 것이다. 해당 클래스는 직접 데이터에 풀링하는것이 아니지만 다른 모든 호출에 연결한다. (creating new Connections on every call)
// DB접근 및 실행을 위한 기본 세팅
@Repository
public class JikwonImpl extends JdbcDaoSupport implements JikwonInter{
새로 생성된 클래스에서 JdbcDaoSupport 클래스를 상속받는다. 상속받게 된다면 해당 클래스에서 jdbcDaoSupport의 멤버 메소드와 필드에 접근 할 수 있다.
@Autowired //DataSource에서 생성한 객체 Bean을 연결
public JikwonImpl(DataSource dataSource) {
setDataSource(dataSource);
}
처음 세팅한 DB세팅을 불러온다. 이때에 해당 DB세팅은 super class인 JdbcDaoSupport의 멤버인 DataSource에 넣어준다. (Setter method 사용)
Spring에서 의존도를 주입하는 방법은 크게 3가지가 있다.
//3. 의존도 주입
@Autowired
private DataSource dataSource;
setDataSource(dataSource)
public JikwonImpl() { //1. 기본 생성자 실행
super.JdbcDaoSupport(); //2. super Class의 생성자 먼저 실행
}
class JikwonRow implements RowMapper {
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
JikwonDto dto = new JikwonDto(); //DTO
dto.setJkiwonno(rs.getInt("jikwonno")); //필드명
dto.setJikwonname(rs.getString("jikwonname")); //필드명
dto.setBusername(rs.getString("busername")); //필드명
dto.setJikwonjik(rs.getString("jikwonjik")); //필드명
return dto;
}
}
RowMapper 인터페이스는 실행된 Query의 결과가 담긴 ResultSet을 행 단위로 매핑하는 인터페이스이다. 실제 작업순서로는 뒤에 언급할 '5) Query 입력 및 실행' 단계가 선행되지만 해당 기능을 설명하기 위해 순서를 바꿔 설명했다.
@Override
public List<JikwonDto> getAlljikwon() {
RowMapper rowMapper = new JikwonRow();
return getJdbcTemplate().query("SELECT j.jikwonno, j.jikwonname, b.busername, j.jikwonjik "
+ "FROM jikwon AS j INNER JOIN buser AS b ON j.busernum = b.buserno ", rowMapper);
}
위의 코드를 통해 쿼리를 입력함으로서 결과값을 반환 할 수 있다. 이때에 주목해야할 메소드는 getJdbcTemplate() 이다. 해당 메소드를 이해하기 위해서는 JdbcTemplate 클래스를 먼저 이해해야하는데 해당 클래스는 Jdbc 코어 패키지의 중요 기능을 호출 할 수 있는 클래스이다. 해당 클래스를 통해 수많은 SQL 기능을 실행 할 수 있다.

JdbcTemplate가 가진 다양한 기능중에 우리는 query() 메소드에 주목해 봐야한다. 해당 메소드는 다양한 방법으로 오버로딩 되어있는데 그중 우리가 사용할 방법은 (String sql, RowMapper) 을 인자로 갖는 메소드를 사용할 것이다. 문자열로 SQL query를 입력해주고 뒤에 앞서 언급한 RowMapper 인터페이스를 입력해준다. 그러면 해당 쿼리가 실행되고 해당 쿼리의 결과의 레코드가 소진될때까지 RowMapper 인터페이스 (예시의 경우 상속받은 클래스)가 반복 실행된다.
query() 메소드는 List 콜렉션을 반환값으로 갖는다. 즉 RowMapper를 상속받은 내부 Class에서 리턴한 DTO가 List 콜렉션에 차곡 차곡 쌓이게 된다.
package pack;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
@Repository
public class JikwonImpl extends JdbcDaoSupport implements JikwonInter {
private DataSource dataSource;
@Autowired
public JikwonImpl(DataSource dataSource) {
setDataSource(dataSource);
}
@Override
public List<JikwonDto> getAlljikwon() {
RowMapper rowMapper = new JikwonRow();
return getJdbcTemplate().query("SELECT j.jikwonno, j.jikwonname, b.busername, j.jikwonjik "
+ "FROM jikwon AS j INNER JOIN buser AS b ON j.busernum = b.buserno ", rowMapper);
}
class JikwonRow implements RowMapper {
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
JikwonDto dto = new JikwonDto();
dto.setJkiwonno(rs.getInt("jikwonno"));
dto.setJikwonname(rs.getString("jikwonname"));
dto.setBusername(rs.getString("busername"));
dto.setJikwonjik(rs.getString("jikwonjik"));
return dto;
}
}
}