템플릿 메서드 패턴
반복적인 로직을 가지는 부분을 캡슐화해서 사용
코딩 순서가 정형화된 기술을 재사용하기 용이하게 모듈화해놓은것
- Template 패턴의 장점
- 코드 중복 감소
- 자식 클래스의 역할을 감소시키면서 핵심로직 관리 용이
- 객체 추가 및 확장을 쉽게 가능
- 재사용성 증가
- Template 패턴의 단점
- 추상 메소드가 너무 많으면 복잡성 증가
- 추상 클래스와 구현 클래스간의 관계 복잡도가 증가
JDBC Template
- 스프링의 가장 기본적인 Data Access 템플릿으로 쿼리 기반으로 데이터 베이스의 접근 가능
- 모든 영속성 프래임워크는 내부적으로 JDBC API를 이용
- DAO 계층에서 Jdbc Template API를 사용
- Data Source
- DB Server와 연결 시키는 연결 팩토리
- JDBC의 일부분
- Connection 의 정보를 가지고 있고 Bean 으로 등록하여 인자를 넘겨줌
- DB Connection Pooling 기능을 가지고 있음
- 기본적으로 BasicDataSource를 사용
JDBC Template 적용 방법
1. 라이브러리 추가
pom.xml 에 추가한 뒤 Maven Dependencies에 잘 적용되었는지 확인
<!-- DBCP -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
2. JdbcTemplate에서 활용할 DataSource 추가
dbcTemplate에서 활용할 DataSource를 컨테이너가 생성할 수 있도록 객체화를 해주어야하는데
이는 <bean>을 통해서 처리함
기존 Util 파일의 정보들은 setter 인젝션 사용하여 DI 를 해줌
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<context:component-scan base-package="com.kim.biz" />
<!-- DataSource 설정하기 -->
<!-- string값을 넣어주기 때문에 ref가 아닌 value로 사용 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
<property name="username" value="kim"/>
<property name="password" value="1234"/>
</bean>
<!-- Spring JDBC 설정하기 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
만약 Spring JDBC 설정하기 부분에서 오류가 난다면
pom.xml에 하기 코드를 추가하면 해결
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
3. DAO 내용 변경
기존 BoardDAO내용을 JdbcTemplate 적용할 BoardDAO2 파일 생성
스프링이 관리하는 Bean을 자동으로 주입해주는 어노테이션인 @Autowired를 사용하여
JdbcTemplate 의 멤버변수가 DI되도록 함
해당 클래스가 DAO라는걸 알리기 위해서 @Repository라고 기입 - 기존 BoardDAO 파일의 @Repository는 삭제
package com.kim.biz.board.impl;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import com.kim.biz.board.BoardVO;
@Repository("boardDAO")
public class BoardDAO2 {
@Autowired
private JdbcTemplate jdbcTemplate;
final String sql_selectOne="SELECT * FROM BOARD WHERE BID=?";
final String sql_selectAll="SELECT * FROM BOARD ORDER BY BID DESC";
final String sql_insert="INSERT INTO BOARD(BID,TITLE,WRITER,CONTENT) VALUES((SELECT NVL(MAX(BID),0)+1 FROM BOARD),?,?,?)";
final String sql_update="UPDATE BOARD SET TITLE=?,CONTENT=? WHERE BID=?";
final String sql_delete="DELETE BOARD WHERE BID=?";
void insertBoard(BoardVO vo) {
jdbcTemplate.update(sql_insert,vo.getTitle(),vo.getWriter(),vo.getContent());
}
void updateBoard(BoardVO vo) {
jdbcTemplate.update(sql_update,vo.getTitle(),vo.getContent(),vo.getBid());
}
void deleteBoard(BoardVO vo) {
jdbcTemplate.update(sql_delete,vo.getBid());
}
BoardVO selectOneBoard(BoardVO vo) {
Object[] args= {vo.getBid()};
return jdbcTemplate.queryForObject(sql_selectOne,args,new BoardRowMapper());
}
List<BoardVO> selectAllBoard(BoardVO vo) {
System.out.println("★★★★★잘들어갔니?? 확인용★★★★★");
return jdbcTemplate.query(sql_selectAll,new BoardRowMapper());
}
}
class BoardRowMapper implements RowMapper<BoardVO>{
@Override
public BoardVO mapRow(ResultSet rs, int rowNum) throws SQLException {
BoardVO data=new BoardVO();
data.setBid(rs.getInt("BID"));
data.setContent(rs.getString("CONTENT"));
data.setTitle(rs.getString("TITLE"));
data.setWriter(rs.getString("WRITER"));
data.setCnt(rs.getInt("CNT"));
data.setRegdate(rs.getString("REGDATE"));
return data;
}
}
JdbcTempate 메서드
update 메서드 - ( INSERT, UPDATE, DELETE 적용)
int update(String sql, Object args, ...)
int update(String sql, Object[] args)
queryForObject() 메서드 - (SELECT문으로 객체 하나를 검색할 때 사용하는 메소드)
Object queryForObject(String sql, Object args, 매핑정보)
-> resultset과 vo를 매핑할 RowMapper 객체를 반드시 지정해야함
ex) SELECT * FROM 테이블명 WHERE PK=?;
List query() 메서드 - (ELECT문의 실행 결과가 목록일 때 사용하는 메소드)
List query(String sql, Object[] args, 매핑정보)
-> 검색 결과를 VO 객체에 매핑하려면 RowMapper 객체를 사용함
4. BoardServiceImpl.java의 @Autowired 연결을 BoardDAO2로 수정
package com.kim.biz.board.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.kim.biz.board.BoardService;
import com.kim.biz.board.BoardVO;
@Service("boardService")
public class BoardServiceImpl implements BoardService {
@Autowired
private BoardDAO2 boardDAO;
@Override
public void insertBoard(BoardVO vo) {
boardDAO.insertBoard(vo);
}
@Override
public void updateBoard(BoardVO vo) {
boardDAO.updateBoard(vo);
}
@Override
public void deleteBoard(BoardVO vo) {
boardDAO.deleteBoard(vo);
}
@Override
public BoardVO selectOneBoard(BoardVO vo) {
return boardDAO.selectOneBoard(vo);
}
@Override
public List<BoardVO> selectAllBoard(BoardVO vo) {
return boardDAO.selectAllBoard(vo);
}
}
JDBCTemplate을 사용하니 훨씬 더 간결한 코드가 완성되는데 너무 신기하다...
'Spring' 카테고리의 다른 글
[Spring] MVC2 패턴 동작과정2 - Spring framework 클래스 적용 (1) | 2022.09.20 |
---|---|
[Spring] MVC2 패턴 동작과정1 (0) | 2022.09.20 |
[Spring] AOP 설정 변환 (xml -> @) (0) | 2022.09.18 |
[Spring] Joinpoint, 바인드 변수 (0) | 2022.09.16 |
[Spring] AOP 관점 지향 프로그래밍, Advice 동작시점 (0) | 2022.09.16 |