본문 바로가기

language/Spring

[Java/Spring] Spring project에 Spring JDBC 설정하기 1

반응형
기존의 JDBC 코드들은 드라이버 로딩, 커넥션 연결, SQL문 전송, 결과 받기 등 일련의 반복된 과정을 수행하도록 구성되어 있습니다. 이런 코드들을 대신해서 처리해주고 관리해주는 것이 바로 Spring JDBC입니다.

 

JdbcTemplate 클래스

JdbcTemplate은 GoF 디자인 패턴 중 템플릿 메서드 패턴이 적용된 클래스 입니다.

템플릿 메서드 패턴은 복잡하고 반복되는 알고리즘을 캡슐화해서 재사용하는 패턴으로 정의할 수 있습니다. (JDBC 코딩처럼 순서가 정형화된 기술에서 유용하게 사용 가능 합니다.)

 

 

Spring JDBC 설정

1. 라이브러리 추가

  • Spring JDBC와 DBCP API 의존성 추가 : mvnrepository.com 에서 spring-jdbc, commons-dbcp2
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${org.springframework-version}</version>
    <!-- spring version 으로 맞춰줬습니다. 5.3.16 -->
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-dbcp2</artifactId>
    <version>2.9.0</version>
</dependency>

 

2. DataSource 설정 (프로퍼티 파일을 활용)

src/main/resources 에 패키지 생성 해서 config 폴더를 생성한 후에 그 곳에 File 생성해서 프로퍼티 파일을 생성

 

  • database.properties
jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@localhost:1521/XEPDB1
jdbc.username=mytest
jdbc.password=mytest

 

  • applicationContext.xml
	<context:component-scan base-package="zinc.spring.web"></context:component-scan> 
	
	<!-- spring jdbc 설정 -->
	<context:property-placeholder location="classpath: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>

 

 

JdbcTemplate 메서드

 

1. update() 메서드 : insert, update, delete 구문 처리 

 

2. queryForObject() 메서드 : select 구문의 실행 결과를 특정 자바 객체로 매핑하여 리턴받을 때 사용

-> 검색결과가 없거나 검색결과가 두 개 이상이면 예외 발생

-> 검색 결과를 자바객체로 매핑할 RowMapper 객체를 반드시 지정

 

3. query() 메서드 : queryForObject() 메서드가 select문으로 하나의 결과를 검색할 때 사용하는 메서드라면 query() 메서드는 select문의 실행 결과가 목록일 때 사용

 

RowMapper() : 검색 결과를 특정 VO 객체에 매핑하여 리턴하려면 RowMapper 인터페이스를 구현한 RowMapper 클래스가 반드시 필요합니다. 결국 RowMapper 클래스는 테이블 당 하나씩은 필요하다는 뜻입니다.

 

 

DAO 클래스 구현

1. JdbcTemplate 클래스 <bean> 등록 및 의존성 주입

  • applicationContext.xml 추가
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>

 

2. BoardDAOSpring 클래스 구현

  • BoardDAOSpring.java
package zinc.spring.web.board.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import zinc.spring.web.board.BoardVO;

@Repository
public class BoardDAOSpring {

	@Autowired // 의존성 주입
	private JdbcTemplate jdbcTemplate;

	private final String BOARD_INSERT = "insert into myboard(seq, title, writer, content) "
			+ "values((select nvl(max(seq), 0)+1 from myboard), ?, ?, ?)";
	private final String BOARD_UPDATE = "update myboard set title=?, content=? where seq=?";
	private final String BOARD_DELETE = "delete myboard where seq=?";
	private final String BOARD_GET = "select * from myboard where seq=?";
	private final String BOARD_LIST = "select * from myboard order by seq desc";
	
	public void insertBoard(BoardVO vo) {
		System.out.println("Spring JDBC로 insertBoard() 기능 처리");
		jdbcTemplate.update(BOARD_INSERT, vo.getTitle(), vo.getWriter(), vo.getContent());
		// try catch 안해도 spring이 해줌
	}
	
	public void updateBoard(BoardVO vo) {
		System.out.println("Spring JDBC로 updateBoard() 기능 처리");
		jdbcTemplate.update(BOARD_UPDATE, vo.getTitle(), vo.getContent(), vo.getSeq());
	}
	
	public void deleteBoard(BoardVO vo) {
		System.out.println("Spring JDBC로 deleteBoard() 기능 처리");
		jdbcTemplate.update(BOARD_DELETE, vo.getSeq());
	}
	
	public BoardVO getBoard(BoardVO vo) {
		System.out.println("Spring JDBC로 getBoard() 기능 처리");
		Object[] args = {vo.getSeq()};
		return jdbcTemplate.queryForObject(BOARD_GET, new BoardRowMapper(), args);
	}
	
	public List<BoardVO> getBoardList(BoardVO vo){
		System.out.println("Spring JDBC로 getBoardList() 기능 처리");
		return jdbcTemplate.query(BOARD_LIST, new BoardRowMapper());
	}
	
	
}

위에 보이는 코드처럼 단순히 쿼리문과 인자들만 넣어주면 jdbc의 규칙적인 구문을 실행하지 않고도 코드 작성이 가능합니다. 사전에 저는 BoardDAO와 Service 클래스인 BoardServiceImple을 엮어주었는데 그것만 추가해서 더 수정해주면 됩니다.

 

3. BoardServiceImpl 클래스 수정

package zinc.spring.web.board.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import zinc.spring.web.board.BoardService;
import zinc.spring.web.board.BoardVO;
import zinc.spring.web.common.LogAdvice;

@Service("boardService")
public class BoardServiceImpl implements BoardService{
	
	@Autowired
	private BoardDAOSpring boardDAO;
	// private BoardDAO 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 getBoard(BoardVO vo) {
		return boardDAO.getBoard(vo);
	}

	@Override
	public List<BoardVO> getBoardList(BoardVO vo) {
		return boardDAO.getBoardList(vo);
	}

}

위처럼 BoardDAOSpring으로 바꿔주면 정상적으로 실행됩니다.

 

4. Controller에서 실행

package zinc.spring.web.board;

import java.util.List;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

public class BoardServiceClient {
	
	public static void main(String[] args) {
		// 1. 스프링 컨테이너 구동
		AbstractApplicationContext container = 
				new GenericXmlApplicationContext("applicationContext.xml");
		
		// 2. 스프링 컨테이너로 부터 BoardServiceImpl 객체를 lookup 한다.
		BoardService boardService = (BoardService)container.getBean("boardService");
		
		// 3. 글 등록 기능 테스트 
		BoardVO vo = new BoardVO();
		vo.setTitle("제목");
		vo.setWriter("이아연");
		vo.setContent("ㅠㅠ");
		
		boardService.insertBoard(vo);
		
		// 4. 글 검색 기능 테스트
		List<BoardVO> boardList = boardService.getBoardList(vo);
		for(BoardVO board : boardList) {
			System.out.println("==> " + board.toString());
		}
		
		// 5. 스프링 컨테이너 종료
		container.close();
	}

}

 

 

위처럼 JdbcTemplate을 사용해도 정상적으로 작동하는 것을 확인할 수 있습니다.

 

 

반응형