일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- JavaScript
- 주니어개발자
- 좋은 PR
- linux 배포판
- CS
- react
- Sparkplug
- 프로세스
- type assertion
- 클라이언트 상태 관리 라이브러리
- jotai
- zustand
- useCallback
- Microtask Queue
- Redux Toolkit
- Custom Hook
- AJIT
- TypeScript
- 암묵적 타입 변환
- 명시적 타입 변환
- Render Queue
- Recoil
- helm-chart
- task queue
- useLayoutEffect
- prettier-plugin-tailwindcss
- docker
- Compound Component
- Headless 컴포넌트
- 타입 단언
- Today
- Total
구리
TIL_210617_SpringFramwork JDBC Template 클래스 사용하여 DB 연동 본문
TIL_210617_SpringFramwork JDBC Template 클래스 사용하여 DB 연동
guriguriguri 2021. 6. 17. 18:11목차
JdbcTemplate 클래스
GoF 디자인 패턴 중 템플릿 메소드 패턴이 적용된 클래스로 반복된 알고리즘을 캡슐화하여 재사용하는 패턴
반복되는 DB 연동 로직은 JdbcTemplate 클래스의 템플릿 메소드가 제공한다
요약
첫 번째 조건 : 라이브러리 추가 (pom.xml)
1. Spring JDBC 라이브러리
2. DBCP 라이브러리
두 번째 조건 : DataSource 설정 : 접속관련 내용..
(DB / myBatis / JPA .... )
common~~.jar
DataSource 역할 : DB 접속 및 커넥션 객체 관리... 등...
방법 1. 프로퍼티 파일을 이용하는 방법
config => database.properties
세 번째 JdbcTemplate 메서드 사용
JdbcTemplate 의 주요 메서드
1. update("쿼리문", 데이터, 데이터....)
update("쿼리문", [데이터])
insert into~~
update ~ set ~~
delete from ~~
과 같은 쿼리를 처리하는 메서드
2. select ~~쿼리를 처리하는 메서드
queryForInt() : 조회된 결과 값이 숫자 일 경우
예) select count(*) from ~~ : 총 레코드의 갯수
select max(seq) from ~~ : seq 필드의 가장 큰값
집계처리 함수에 대한 결과
queryForInt("쿼리문")
queryForInt("쿼리문", 데이터, 데이터...)
queryForInt("쿼리문", [데이터])
queryForObject() : 조회된 결과 레코드수가 1개일 경우
(결과가 없거나, 두 개이상일 경우에는 예외처리)
예) select * from ~~~ where seq=?
상세보기 부분에 해당...
queryForObject("쿼리문")
queryForObject("쿼리문",반환객체)
queryForObject("쿼리문", [데이터], 반환객체)
queryForObject()는 쿼리 실행 후, mapRow() 1회만 자동 호출
반환객체에 대한 클래스 설계시 RowMapper 인터페이스를 구현받는다
예) public class TestMapper implements RowMapper<VO>{
// RowMapper의 추상메서드 재정의
@Override
public VO mapRow(ResultSet rs, int rowNum) throws SQLException{
VO vo=new VO();
vo.set~~~(rs.get~~~());
return vo;
}
}
query() : 조회된 결과 레코드 수가 1개 이상일 경우
예) select * from ~~
select * from ~~ order by seq desc;
목록이나 검색에 해당..
List query("쿼리문")
List query("쿼리문",반환객체)
List query("쿼리문", [데이터], 반환객체)
query()는 쿼리 실행 후, mapRow() 결과레코드 갯수만큼 자동 호출.
query()는 mapRow()가 호출될 때마다 그 결과 vo를 List 에 저장하여
최종 List<VO> 형태로 리턴한다...
반환객체에 대한 클래스 설계시 RowMapper 인터페이스를 구현받는다
예) public class TestMapper implements RowMapper<VO>{
// RowMapper의 추상메서드 재정의
@Override
public VO mapRow(ResultSet rs, int rowNum) throws SQLException{
VO vo=new VO();
vo.set~~~(rs.get~~~());
return vo;
}
}
===================================
DAO 클래스 구현
첫 번째 방법 : JdbcDaoSupport 클래스 상속
메서드 주입방식을 사용..
예) @Autowired
public void set~~~(DataSource dataSource){
super.setDataSource(dataSource);
}
쿼리 실행 메서드는 JdbcDaoSupport 에 정의된
getJdbcTemplate()를 통해 호출하여 사용..
예) getJdbcTemplate().update("쿼리문");
두 번째 방법 : JdbcTemplate 클래스 <bean> 등록 =>의존성 주입
해당 DAO 클래스 내에 멤버변수를 선언
예) @Autowired
private JdbcTemplate jdbcTemplate;
쿼리 실행 메서드는 주입받은 jdbcTemplate객체의 메서드를 호출
예) jdbcTemplate.update("쿼리문");
1. 라이브러리 추가(pom.xml)
- pom.xml에 Spring jdbc & DBCP 관련 dependency 태그 추가
(참고로 필자의 스프링 버전은 4.2.4 톰캣 8, 자바 8버전입니다.)
<!-- Spring JDBC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- DBCP : DataBase Connection Pool -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
- 태그 추가 후 xml 문서를 저장하면 라이브리러에 4개의 jar 파일이 추가된 것을 볼 수 있습니다.
(spring-jdbc, spring-tx, commons-dbcp, commons-pool.jar)
2. DataSource 설정 (접속 관련 내용 설정, commons.jar 파일 사용하기에 어노테이션 사용 불가)
JdbcTemplate 객체가 사용할 DataSource를 <bean> 등록하여 스프링 컨테이너가 생성하도록 합니다.
이 설정은 JDBC / MyBatis연동 / JPA 연동에서도 사용되며 applicationContext.xml에서 직접 설정하는 방법과 config 문서로 만들어서 xml 문서로 읽어와 설정하는 방법이 있습니다.
1) applicationContext.xml에서 DB 관련 정보를 직접 작성
applicationContext.xml 문서에 DataSource 관련 설정 (BasicDataSource는 일반적으로 가장 많이 사용하는 Apache의 클래스로 DataSource 인터페이스를 구현)(아래와 같이 property name 속성값은 변경 불가! 미리 지정된 이름이기 때문에 value 값만 설정하면 됩니다)
<!-- DataSource 설정 -->
<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="bjy" />
<property name="password" value="qorwjddus96" />
</bean>
2) 프로퍼티 파일을 이용하는 방법 (config => database.properties)
src/main/resource 폴더에서 config 폴더 생성 후 db 관련 텍스트파일 생성 (확장자는 .properties로 파일명은 변경하여도 가능)
(src/main/resource 폴더는 앱 관련 설정파일들 담는 공간)
jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:XE
jdbc.username=bjy
jdbc.password=qorwjddus96
xml 문서에 설정
<!-- DataSource Configuration properties 파일 이용 -->
<context:property-placeholder location="classpath:config/database.properties"/>
<bean id="dataSource" class="org.commons.dbcp.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>
프로퍼티 파일 사용을 위해선 <bean> 등록 전에 <context:property-placeholder> 엘리먼트로 프로퍼티 파일의 위치를 등록해야 합니다
3. JdbcTemplate클래스의 메서드 사용
위에서 생성한 DateSource 객체를 JdbcTemplate 클래스에게 주입시켜 줍니다.
<!-- Spring JDBC -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
(1) update()
INSERT, UPDATE, DELETE 구문을 처리하기 위해 사용
① int update(String sql, Objects ...agrs) - SQL 구문에 설정된 ? 수만큼 매개변수로 전달
예시
// 글 수정
public void updateBoard(BoardVO vo){
System.out.println("===>Spring JDBC로 updateBoard() 기능 처리");
jdbcTemplate.update(BOARD_UPDATE, vo.getTitle(), vo.getWriter(), vo.getContent());
}
② int update(String sql, Objects ...agrs) - SQL 구문에 설정된 ? 수만큼 값들을 세팅하여 배열 객체를 두 번째 인자로 전달
// 글 수정
public void updateBoard(BoardVO vo){
System.out.println("===>Spring JDBC로 updateBoard() 기능 처리");
Object[] args = { vo.getTitle(), vo.getWriter(), vo.getContent() };
jdbcTemplate.update(BOARD_UPDATE, args);
}
(2) queryForInt()
select 구문으로 검색된 정숫값 리턴 받을 시 사용하며 페이징 작업시 사용
① int queryForInt(String sql)
② int queryForInt(String sql, Objects ... args)③ int queryForInt(String sql, Objects[] args)
(3) queryForObejct()
Object queryForObject(String sql, [ Object[] args | RowMapper<T> rowMapper ] )
select 구문으로 결과값이 1개의 레코드만 나오는 경우 사용 (상세보기)
검색 결과를 자바 객체로 매핑할 RowMapper 인터페이스 구현한 객체를 반드시 지정해야 함(전에 DAO 클래스 메서드 실행 후 전달할 값이 있다면 VO 객체 생성 후 데이터를 저장하여 넘겼던 작업을 RowMapper 인터페이스 구현한 클래스로 한번에 해결)
package com.springbook.biz.board.impl;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
import com.springbook.biz.board.BoardVO;
/** JdbcTemplate의 메서드 중 queryForObject(), query() 메서드에 대한 반환 타입으로 사용**/
public class BoardRowMapper implements RowMapper<BoardVO> {
public BoardRowMapper() {}
/** mapRow() 메서도는 SQL 쿼리 실행 후 , 스프링 컨테이너가 자동 호출 **/
// rs : sql 쿼리 실행 결과
// rowNum : 쿼리 실행 결과에 대한 레코드 수
@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;
}
}
RowMapper 객체를 queryForObejct() 메소드의 매개변수로 넘겨주면, 스프링 컨테이너는 SQL 문 수행한 후 자동으로 RowMapper 객체의 mapRow() 메소드를 호출합니다.
(4)query()
select 문의 실행 결과가 목록일 때 사용
검색 결과를 자바 객체에 매핑할 RowMapper 인터페이스 구현한 객체를 반드시 지정해야 함
메소드 | List query(String sql) List query(String sql, RowMapper<T> rowMapper) List query(String sql, Objects[] args, RowMapper rowMapper) |
사용 예 | // 글 목록 조회 public List<BoardVO> getBoardList(BoardVO vo){ String BOARD_LIST = "select * form board order by seq desc"; return jdbcTemplate.query(BOARD_LIST, new BoardRowMapper()); |
query() 메소드 실행시 여러 건의 ROW 정보 검색 => ROW 수만큼 mapRow() 메소드 실행 => ROW 정보가 매핑된 VO 객체 여러 개가 List 컬렉션에 저장되어 리턴.
4. DAO 클래스 구현
1) JdbcDaoSupport 클래스 상속 - 메서드 주입 방식을 사용
import java.util.List;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;
import com.springbook.biz.board.BoardVO;
public class BoardDAOSpring extends JdbcDaoSupport {
private final String BOARD_INSERT = "insert into board(seq, title, writer, content) values ((select nvl(max(seq), 0)+1 from board),?,?,?)";
private final String BOARD_UPDATE = "update board set title=?, content=?, where seq=?";
private final String BOARD_DELETE = "delete from board where seq=?";
private final String BOARD_GET = "select * from board where seq=?";
private final String BOARD_LIST = "select * from board order by seq desc";
@Autowired
public void setSuperDataSource(DataSource dataSource){
super.setDataSource(dataSource);
}
public BoardDAOSpring() { }
// 글 등록
public void insertBoard(BoardVO vo){
System.out.println("===>Spring JDBC로 insertBoard() 기능 처리");
getJdbcTemplate().update(BOARD_INSERT, vo.getTitle(), vo.getWriter(), vo.getContent());
}
}
@Autowired 어노테이션으로 인해 xml에서 생성한 BasicDataSource 객체를 주입받게 되며 쿼리 실행 메서드는 JdbcDaoSupport에 정의된 getJdbcTemplate()를 통해 호출하여 사용합니다.
(참고로 setDataSource()는 JdbcDaoSupport 클래스의 메소드로 데이터 소스 객체를 의존성 주입한다)
2) JdbcTemplate 클래스 <bean>등록, 의존성 주입
<!-- Spring JDBC Configuration-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
- 해당 DAO 클래스 내에 멤버변수를 선언하고 @Autowired 어노테이션 이용
package com.springbook.biz.board.impl;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;
import com.springbook.biz.board.BoardVO;
// DAO
@Repository
public class BoardDAOSpring{
@Autowired
private JdbcTemplate jdbcTemplate;
private final String BOARD_INSERT = "insert into board(seq, title, writer, content) values ((select nvl(max(seq), 0)+1 from board),?,?,?)";
private final String BOARD_UPDATE = "update board set title=?, content=?, where seq=?";
private final String BOARD_DELETE = "delete from board where seq=?";
private final String BOARD_GET = "select * from board where seq=?";
private final String BOARD_LIST = "select * from board order by seq desc";
public BoardDAOSpring() { }
// 글 등록
public void insertBoard(BoardVO vo){
System.out.println("===>Spring JDBC로 insertBoard() 기능 처리");
jdbcTemplate.update(BOARD_INSERT, vo.getTitle(), vo.getWriter(), vo.getContent());
}
}
마지막으로 JdbcTemplate 객체를 이용하여 BoardDAOSpring 클래스를 구현했으면 BoardServiceImpl 클래스가 BoardDAOSpring 객체를 이용하여 DB 연동 처리하도록 수정하면 됩니다.
@Service("boardSerivce")
public class BoardServiceImpl implements BoardService {
@Autowired
private BoardDAOSpring boardDAO;
public void insertBoard(BoardVO vo) {
boardDAO.insertBoard(vo);
}
}
'SPRING FRAMEWORK' 카테고리의 다른 글
TIL_210618_AOP (0) | 2021.06.18 |
---|---|
TIL_210617_AOP 정의, 적용하는 법, 용어, 엘리먼트 (0) | 2021.06.17 |
TIL_210616_컬렉션 객체 맵핑 설정, DI 설정(어노테이션, XML 설정) (0) | 2021.06.16 |
TIL_210615_스프링 XML 설정 및 속성, 의존성 관리 종류 (0) | 2021.06.15 |
STS 설치 및 Spring Legacy Project 최초 생성, 오류 해결 (0) | 2021.06.15 |