day68) Spring - Model 설계2 : JDBC Template
https://code-learning.tistory.com/106?category=1011627
day62) Spring - Model 설계
[기본적인 게시판 CRUD를 활용한 Spring Framework 모델구조 만들기] -com.test.app.board 패키지에서는 객체화 되어 사용되지 않는 클래스 :BoardService(interface), BoardVO -com.test.app.board.impl 패키지에..
code-learning.tistory.com
[JDBC template이란?]
-템플릿 패턴
동일하진 않지만, 유사한 코드가 반복되는 패턴에서 사용되는 패턴을 템플릿 패턴이라고 부른다.
템플릿 패턴을 사용하게 된다면 반복되거나 복잡한 알고리즘을 캡슐화하게 되어 재사용성이 증가한다.
: 위에 제공한 주소에서는 JDBCUtil클래스를 통해 공통로직을 빼서 사용했다.
: 하지만 유사하게 반복되는코드들이 너무 많기 때문에 이를 JDBCTemplate으로 맡겨보자
=> JDBCTemplate
: 유사하게 반복되는 DB관련로직을 Template클래스에서 제공받고,
개발자는 설정, 설정값(SQL구문, 매핑)들만 신경쓰면 된다.
[사용방법]
1. 라이브러리 추가: pom.xml에 설정 추가
<!-- 스프링 JDBC를 위한 DBCP -->
<dependency><!--1-->
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency><!--2-->
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
1번만 사용해도 잘 적용이 되는 사람이 있는데 나는 1번만으로는 안되서 2번까지 추가해서 사용했다.
DBCP는 커넥션을 확보하여 커넥션 풀을 생성하는데 목적이 있다.
-> 이미 여러개 연결되어있는 커넥션들의 풀을 dbcp가 가지고 있고, sql문을 사용할 일이 생겼을 때 확보해둔 커넥션을 사용자에게 제공하고, 사용자가 사용을 마쳤다면 원래대로 돌려놓는 방식
-> 다중 사용자 이용시 이점이 있다.
2. DataSource 생성 - applicationContext.xml에서 객체 생성
JDBCTemplate이 DB연동을 하려면 커넥션을 확보해야한다.
JDBCTemplate이 사용할 DataSource를 스프링 컨테이너가 생성할 수 있도록 <bean>해주어야한다.
<!-- DataSource 설정 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!-- destroy-method="close": 연결해제 메서드 -->
<!-- setter injection -->
<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>
3.DAO 생성
1) JDBCTemplate을 applicationContext.xml에서<bean>으로 생성하여 위에서 생성한 dataSource를 DI한다.
<!-- JdbcTemplate 생성 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<context:component-scan base-package="com.test.app" />
2) DAO사용하기
package com.test.app.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.test.app.board.BoardVO;
@Repository("boardDAO")
public class BoardDAO2 {
// Spring에서 제공하는 JDBC.JDBCTemplate
// JDBCTemplate을 <bean>으로 생성해서 DI주입해서 사용 ★
@Autowired//타입을 보고 일치하는 생성된 객체와 mapping한다
private JdbcTemplate jdbcTemplate;
private final String BOARD_INSERT="insert into board values((select nvl(max(bid),0)+1 from board),?,?,?)";
private final String BOARD_SELECTONE="select * from board where bid=?";
private final String BOARD_SELECTALL="select * from board order by bid desc";
private final String BOARD_UPDATE="update board set title=?,content=? where bid=?";
private final String BOARD_DELETE="delete board where bid=?";
public void insertBoard(BoardVO vo) {
System.out.println("insertBoard() 호출됨");
jdbcTemplate.update(BOARD_INSERT, vo.getTitle(),vo.getWriter(),vo.getContent());
}
public BoardVO getBoard(BoardVO vo) {
System.out.println("getBoard() 호출됨");
Object[] args= {vo.getBid()};
//BoardRowMapper()-> 어떻게 연결할 것인가
return jdbcTemplate.queryForObject(BOARD_SELECTONE, args, new BoardRowMapper());
}
// 검색을 위한 비즈니스 메서드를 따로 작성xxx
// 인자변경 -> 불리점 => VO에 멤버변수로 추가!
public List<BoardVO> getBoardList(BoardVO vo) {
System.out.println("getBoardList() 호출됨");
return jdbcTemplate.query(BOARD_SELECTALL, new BoardRowMapper());
}
public void updateBoard(BoardVO vo) {
jdbcTemplate.update(BOARD_UPDATE, vo.getTitle(),vo.getContent(),vo.getBid());
}
public void deleteBoard(BoardVO vo) {
jdbcTemplate.update(BOARD_DELETE, vo.getBid());
}
}
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"));
return data;
}
}
[JDBC Template에서 사용하는 메서드]
1) update()
INSERT, UPDATE, DELETE를 수행할 때 활용한다
이때 ?를 처리하는 방법으로 2가지가 있다.
- 인자를 직접, 각각 연결
jdbcTemplate.update(SQL, vo.getxxx(),vo.getxxx(),...);
- 배열에 저장하여 한번에 연결
Object[] args={vo.getxxx(), vo.getxxx(), ...};
jdbcTemplate.update(SQL, args);
2) queryForInt(): 정수 output에 대해 사용한다.
SELECT : SELECT COUNT(*) FROM 테이블 WHERE 조건절;
3) queryForObject() : 객체 output에 사용
SELECT * FROM 테이블명 WHERE 조건절;
SELECT : 검색결과가 하나일 때 사용한다.
☆검색 결과가 없거나, 두개 이상이면 예외발생! ex)로그인
검색결과 -> 자버객체(VO) 설정필요!!! => RowMapper
RowMapper :어떤 테이블의 결과를 어떤 VO로 볼지에 대한 설정
테이블:VO=1:1이여야 한다.
4)query()
SELECT * FROM 테이블명 WHERE 조건절;
SELECT : 검색결과가 여러개(List)일 때 사용한다
RowMapper를 검색결과만큼 사용함 == mapRow()를 검색결과만큼 호출
사용결과를 List에 저장하여 보내준다.