티스토리 뷰
기존 DAO 클래스 구성을 보면 코드 양이 상당히 길어지는 단점이 있다.
JDBCUtil 클래스를 이용하여 커넥션 연결과 해제 로직을 대체한다고 하더라도 많은 양의 코드가 필요하고, 다른 메소드들을 구현할 때마다 반복해서 작성해야 한다는 단점이 있다.
스프링은 이러한 문제를 해결함과 동시에 JDBC 기반의 DB 연동 프로그램을 쉽게 개발할 수 있도록 JdbcTemplate 클래스를 지원한다.
1. JdbcTemplate 클래스
JDBC의 반복적인 코드를 제거하기 위해 제공하는 클래스.
따라서 DAO 클래스에서는 JdbcTemplate 클래스가 제공하는 템플릿 메소드를 호출하여 DB 연동을 간단하게 처리.
JdbcTemplate 클래스 내부적으로 JDBC API를 이용하여 실제 DB 연동 작업을 처리하기 때문에 개발자는 전혀 신경 쓸 필요가 없다.
build.gradle에 dependencies 아래 다음 추가
implementation 'org.apache.commons:commons-dbcp2:2.9.0' // DBCP 라이브러리 추가
resources/config 아래 database.properties 파일에 다음 추가
jdbc.driver=org.h2.Driver
jdbc.url=jdbc:h2:tcp://localhost/~/MySpring
jdbc.username=sa
jdbc.password=
spring.datasource.driver-class-name=org.h2.Driver
applicationContext.xml에 다음 추가
<!-- DataSource 설정 !-->
<context:property-placeholder location="config/database.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
DAO 클래스 구현
- RowMapper 클래스
검색 결과를 특정 VO 객체에 매핑하여 리턴하려면 RowMapper 인터페이스를 구현한 RowMapper 클래스가 필요하다.
결국 RowMapper 클래스는 테이블당 하나씩 필요하다는 말이다.
그리고 mapRow() 메소드를 오버라이딩하여 검색 결과로 얻어낸 Row 정보를 어떤 VO에 어떻게 매핑할지 구현한다.
RowMapper 객체를 query() 메소드의 매개변수로 넘겨주면, 스프링 컨테이너는 SQL 구문을 실행 후 자동으로 mapRow() 메소드를 호출한다.
class BoardRowMapper implements RowMapper<BoardVO> {
@Override
public BoardVO mapRow(ResultSet rs, int rowNum) throws SQLException {
BoardVO board = new BoardVO();
board.setSeq(rs.getInt("SEQ"));
board.setTitle(rs.getString("TITLE"));
board.setWriter(rs.getString("WRITER"));
board.setContent(rs.getString("CONTENT"));
board.setRegDate(rs.getDate("REGDATE"));
board.setCnt(rs.getInt("cnt"));
return board;
}
}
// ...
public BoardVO getBoard(BoardVO vo) {
System.out.println("[Spring JDBC] getBoard() 실행");
Object[] args = {vo.getSeq()};
return getJdbcTemplate().queryForObject(BOARD_GET, args, new BoardRowMapper());
}
// 글 목록 조회
public List<BoardVO> getBoardList(BoardVO vo) {
System.out.println("[Spring JDBC] getBoardList() 실행");
return getJdbcTemplate().query(BOARD_LIST, new BoardRowMapper());
}
JdbcTemplate 객체를 얻는 방법은 다음 두가지가 존재한다.
- JdbcDaoSupport 클래스 상속
@Repository
public class BoardDAOSpring extends JdbcDaoSupport {
...
@Autowired
public void setSuperDataSource(DataSource dataSource) {
super.setDataSource(dataSource);
}
// 글 등록
public void insertBoard(BoardVO vo) {
System.out.println("[Spring JDBC] insertBoard() 실행");
getJdbcTemplate().update(BOARD_INSERT, vo.getTitle(), vo.getWriter(), vo.getContent());
}
DAO 클래스를 구현할 때, JdbcDaoSupport 클래스를 상속받으면 getJdbcTemplate() 메소드를 상속받을 수 있다.
getJdbcTemplate() 메소드를 호출하면 JdbcTemplate 객체가 리턴된다.
이때 DataSource 객체가 필요하기 때문에 부모 클래스의 setDataSource() 메소드를 호출하여 DataSource 객체를 의존성 주입해야 한다.
- JdbcTemplate 클래스 <bean> 등록 후, 의존성 주입
일반적으로 이 방법을 사용한다.
<!-- DataSource 설정 !-->
<context:property-placeholder location="config/database.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- Spring JDBC 설정 !-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
JdbcTemplate 클래스를 <bean> 등록하고 다음과 같이 의존성 주입한다.
@Repository
public class BoardDAOSpring {
private JdbcTemplate jdbcTemplate;
// ...
@Autowired
public BoardDAOSpring(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void insertBoard(BoardVO vo) {
System.out.println("[Spring JDBC] insertBoard() 실행");
jdbcTemplate.update(BOARD_INSERT, vo.getTitle(), vo.getWriter(), vo.getContent());
}
// ...
}
이 방법을 사용하면 JdbcDaoSupport 클래스를 상속할 필요가 없고, getJdbcTemplate() 메소드 대신 주입받은 변수를 이용한다.
'Spring' 카테고리의 다른 글
06 - 3. 어노테이션 기반 AOP (0) | 2022.11.13 |
---|---|
06 - 2. 어드바이스 동작 시점, JoinPoint, 바인드 변수 (0) | 2022.11.09 |
06 - 1. Aspect Oriented Programming (0) | 2022.11.09 |
05. 비즈니스 컴포넌트 실습 (0) | 2022.10.31 |
04. 어노테이션 기반 설정 (0) | 2022.10.30 |