실습 코드 참조
moonhy7/SpringFramework: Spring Framework 실습 코드 정리 (github.com)
6.1절 스프링 JDBC 개념
1. 스프링 JDBC 개념
1) JDBC 특성
- 가장 오랫동안 자바 개발자들이 사용한 DB 연동 기술
- JDBC를 이용하여 DB 연동 프로그램을 개발하면 데이터베이스에 비종속적인 DB 연동 로직을 구현할 수 있음
- 개발자가 작성해야 할 코드가 너무 많다는 단점
2) UserDAO 클래스
- 아이디어 비밀번호를 입력 후 매칭되는 회원 정보 조회 기능
- JDBCUtil 클래스를 이용하여 커넥션 연결과 해제 로직을 대체해도 코드가 길다.
- 다른 메소드들을 구현할 때마다 반복해서 작성해야 한다는 단점도 있음
package com.springbook.biz.user.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import org.springframework.stereotype.Repository;
import com.springbook.biz.common.JDBCUtil;
import com.springbook.biz.user.UserVO;
@Repository("userDAO")
public class UserDAO {
//JDBC 관련 변수들
private Connection conn = null;
private PreparedStatement stmt = null;
private ResultSet rs = null;
//SQL 명령어
private final String USER_GET = "SELECT * FROM USERS WHERE ID = ? AND PASSWORD = ?";
//CRUD 기능의 메소드 구현
//회원 상세 조회
public UserVO getUser(UserVO vo) {
UserVO user = null;
try {
conn = JDBCUtil.getConnection();
stmt = conn.prepareStatement(USER_GET);
stmt.setString(1, vo.getId());
stmt.setString(2, vo.getPassword());
rs = stmt.executeQuery();
if(rs.next()) {
user = new UserVO();
user.setId(rs.getString("ID"));
user.setPassword(rs.getString("PASSWORD"));
user.setName(rs.getString("NAME"));
user.setRole(rs.getString("ROLE"));
}
} catch(Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.close(rs, stmt, conn);
}
return user;
}
}
3) BoardDAO 클래스
- JDBCUtil 클래스를 사용하여 구현한 클래스
- UserDAO 클래스의 자바 코드가 거의 일치함
package com.springbook.biz.board.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Repository;
import com.springbook.biz.board.BoardVO;
import com.springbook.biz.common.JDBCUtil;
@Repository("boardDAO")
public class BoardDAO {
//JDBC 관련 변수
private Connection conn = null;
private PreparedStatement stmt = null;
private ResultSet rs = null;
//SQL 관련 명령어
//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_INSERT = "INSERT INTO studydb.BOARD(SEQ, TITLE, WRITER, CONTENT) "
+ "VALUES((SELECT IFNULL(MAX(SEQ), 0) + 1 FROM BOARD A), ?, ?, ?)";
private final String BOARD_UPDATE = "UPDATE studydb.BOARD SET TITLE = ?, CONTENT = ? WHERE SEQ = ?";
private final String BOARD_DELETE = "DELETE FROM studydb.BOARD WHERE SEQ = ?";
private final String BOARD_GET = "SELECT * FROM studydb.BOARD WHERE SEQ = ?";
private final String BOARD_LIST = "SELECT * FROM studydb.BOARD ORDER BY SEQ DESC";
//CRUD 기능의 메소드 구현
//글 등록
public void insertBoard(BoardVO vo) {
System.out.println("====> JDBC로 insertBoard() 기능 처리");
try {
conn = JDBCUtil.getConnection();
stmt = conn.prepareStatement(BOARD_INSERT);
stmt.setString(1, vo.getTitle());
stmt.setString(2, vo.getWriter());
stmt.setString(3, vo.getContent());
stmt.executeUpdate();
} catch(Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.close(stmt, conn);
}
}
//글 수정
public void upadateBoard(BoardVO vo) {
System.out.println("====> JDBC로 upadateBoard() 기능 처리");
try {
conn = JDBCUtil.getConnection();
stmt = conn.prepareStatement(BOARD_UPDATE);
stmt.setString(1, vo.getTitle());
stmt.setString(2, vo.getContent());
stmt.executeUpdate();
} catch(Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.close(stmt, conn);
}
}
//글 삭제
public void deleteBoard(BoardVO vo) {
System.out.println("====> JDBC로 deleteBoard() 기능 처리");
try {
conn = JDBCUtil.getConnection();
stmt = conn.prepareStatement(BOARD_DELETE);
stmt.setInt(1, vo.getSeq());
stmt.executeUpdate();
} catch(Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.close(stmt, conn);
}
}
//글 상세 조회
public BoardVO getBoard(BoardVO vo) {
System.out.println("====> JDBC로 getBoard() 기능 처리");
BoardVO board = null;
try {
conn = JDBCUtil.getConnection();
stmt = conn.prepareStatement(BOARD_GET);
stmt.setInt(1, vo.getSeq());
rs = stmt.executeQuery();
if(rs.next()) {
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"));
}
} catch(Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.close(rs, stmt, conn);
}
return board;
}
//글 목록 조회
public List<BoardVO> getBoardList(BoardVO vo) {
System.out.println("====> JDBC로 getBoard() 기능 처리");
List<BoardVO> boardList = new ArrayList<BoardVO>();
try {
conn = JDBCUtil.getConnection();
stmt = conn.prepareStatement(BOARD_LIST);
rs = stmt.executeQuery();
while(rs.next()) {
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"));
boardList.add(board);
}
} catch(Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.close(rs, stmt, conn);
}
return boardList;
}
}
4) 스프링에서 지원하는 JdbcTemplate 클래스
- 새로운 기능의 메소드를 개발하려면 결국 기존의 메소드를 복사하여 SQL만 수정하는 방법 뿐임
- 스프링은 JDBC 기반의 DB 연동 프로그램을 쉽게 개발할 수 있도록 JdbcTemplate 클래스를 지원함
- 개발자는 DB 연동에 필요한 자바 코드를 작성하지 않아도 되고 SQL 구문 관리만 하면 되므로 훨씬 편리해짐
6.2절 JdbcTemplate 클래스
1) JDBCTemplate의 위치와 역할
- JDBCTemplate : GoF 디자인 패턴 중 템플릿 메소드 패턴이 적용된 클래스
- 템플릿 메소드 패턴 : 복잡하고 반복되는 알고리즘을 캡슐화하여 재사용하는 패턴
- JDBC처럼 코딩 순서가 정형화된 기술에서 유용하게 사용할 수 있음
- 반복되는 DB 연동 로직은 JdbcTemplate 클래스의 템플릿 메소드가 제공하고, 개발자는 달라지는 SQL 구문과 설정값만 신경 쓰면 됨
2) JDBCTemplate의 위치와 역할
- JDBCTemplate : JDBC의 반복적인 코드를 제거하기 위해 제공하는 클래스
- DAO 클래스에서는 JDBCTemplate 클래스가 제공하는 템플릿 메소드를 호출하여 DB 연동을 간단하게 처리함
- JDBCTemplate 클래스는 내부적으로 JDBC API를 이용하여 실제 DB 연동 작업을 처리함
- 개발자는 JDBCTemplate 클래스가 어떻게 JDBC AP를 이용하는지는 전혀 신경 쓸 필요가 없음
6.3절 스프링 JDBC 설정
1. 라이브러리 추가
- 스프링 JDBC를 이용하려면 pom.xml 파일에 DBCP 관련 <dependency> 설정을 추가해야함
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- DBCP -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
- <dependency> 설정을 추가한 후 DBCP 라이브러리가 정상 등록되었는지 확인
2. DataSource 설정 ( _045_BoardWeb_JDBC_DataSource )
1) DataSource 설정 이유
- JDBCTemplate 클래스가 JDBC API를 이용해서 DB 연동을 처리하려면 반드시 데이터베이스로부터 커넥션을 얻어야함
- JDBCTemplate 객체가 사용할 DataSource를 <bean> 등록하여 스프링 컨테이너가 생성되도록 해야함
- DataSource 설정은 이후 트랜잭션 처리나 Mybatis 연동, JPA 연동에서도 DataSource가 사용되므로 매우 중요한 설정임
2) DataSource 설정
- BasicDataSource 객체는 연결에 필요한 프로퍼티들을 Setter 인젝션으로 설정해주면 된다.
- BasicDataSource 객체가 삭제되기 전에 연결을 해제하고자 close() 메소드를 destroy-method 속성으로 지정함
<!-- DataSource 설정 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!-- MySQL -->
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/studydb?serverTimeZone=UTC"></property>
<property name="username" value="study"></property>
<property name="password" value="study"></property>
</bean>
3. 프로퍼티 파일을 활용한 DataSource 설정 ( _046_BoardWeb_JDBC_Properties )
1) datasource.properties
- resources 폴더에 config 폴더를 생성하고 datasource.properties 파일을 작성하기
- PropertyPlaceholderConfigurer를 이용하면 외부의 프로퍼티 파일을 참조하여 설정 가능
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/studydb?serverTimeZone=UTC
jdbc.username=study
jdbc.password=study
2) 설정 파일
- 위에 프로퍼티스 파일에 설정된 프로퍼티들을 이용하여 DataSource를 설정하려면 스프링 설정 파일에 <context:property-placeholder> 엘리먼트를 사용하여 위치를 등록해준다.
-그리고 ${ } 구문을 이용하여 프로퍼티 이름을 지정하면 프로퍼티 값으로 치환되어 실행됨
!-- DataSource 설정 -->
<!-- 외부 properties 파일 참조 -->
<context:property-placeholder location="classpath:config/datasource.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!-- MySQL -->
<property name="driverClassName" value="{jdbc.driver}"></property>
<property name="url" value="{jdbc.url}"></property>
<property name="username" value="{jdbc.username"></property>
<property name="password" value="{jdbc.password}"></property>
</bean>
6.4절 JdbcTempate 메소드
1. update() 메소드
1) update() 메소드를 사용하는 첫 번째 방법
- SQL 구문에 설정된 ? 수만큼 값들을 차례로 나열
2) update() 메소드를 사용하는 두 번째 방법
- Object 배열 객체에 SQL 구문에 설정된 ? 수만큼의 값들을 세팅하여 배열 객체를 두 번째 인자로 전달
2. queryForInt() 메소드
- SELECT 구문으로 검색된 정숫값을 리턴받으려면 queryForInt() 메소드를 사용함
3. queryForObject() 메소드 ( _047_BoardWeb_JDBC_RowMapper )
1) queryForObject() 메소드
- queryForObject() 메소드는 SELECT 구문의 실행 결과를 특정 자바 객체로 매핑하여 리턴받을 때 사용한다.
- queryForObject() 메소드는 검색 결과가 없거나 검색 결과가 두 개 이상이면 예외를 발생시킴
- 검색 결과를 자바 객체로 매핑할 RowMapper 객체를 반드시 지정해야함
2) RowMapper 클래스
- 검색 결과를 특정 VO 객체에 매핑하여 리턴하려면 RowMapper 인터페이스를 구현한 RowMapper 클래스가 필요함(RowMapper 클래스는 테이블당 하나씩은 필요하다는 의미)
- RowMapper 인터페이스에는 mapRow() 메소드가 있어 검색 결과로 얻어낸 Row 정보를 어떤 VO에 어떻게 매핑할 것인지 구현해주면 된다.
3) BoardRowMapper 클래스
- RowMapper 객체를 queryForObject() 메소드의 매개변수로 넘겨주면 스프링 컨테이너는 SQL 구문 수행 후 자동으로 RowMapper 객체의 mapRow() 메소드를 호출함
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;
public class BoardRowMapper implements RowMapper<BoardVO> {
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;
}
}
4. query() 메소드
1) query() 메소드
- queryForObject() : SELECT문으로 객체 하나를 검색할 때 사용하는 메소드
- query() 메소드 : SELECT문의 실행 결과가 목록일 때 사용하는 메소드
- query() 메소드에서도 검색 결과를 VO 객체에 매핑하려면 RowMapper 객체를 사용함
- query() 메소드가 실행되면 여러 건의 ROW 정보가 검색되며 검색된 데이터 ROW 수만큼 RowMapper 객체의 mapRow() 메소드가 실행됨
- 이렇게 ROW 정보가 매핑된 VO 객체 여러 개가 List 컬렉션에 저장되어 리턴된다.
6.5절 DAO클래스 구현
- DAO 클래스에서 JdbcTemplate 객체를 얻는 방법은 두 가지가 있다.
1. 첫 번째 방법 : JdbcDaoSupport 클래스 상속 ( _048_BoardWeb_JDBC_DAOSupport )
1) BoardDAOSpring
- DAO 클래스를 구현할 때, JdbcDaoSupport 클래스를 부모 클래스로 지정하면 getJdbcTemplate() 매소드를 상속받을 수 있다.
- 또한, getJdbcTemplate() 메소드를 호출하면 JdbcTemplate 객체가 리턴되어 모든 메소드를 JdbcTemplate 객체로 구현할 수 있다.
package com.springbook.biz.board.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;
import com.springbook.biz.board.BoardVO;
import com.springbook.biz.common.JDBCUtil;
@Repository("boardDAO")
public class BoardDAOSpring extends JdbcDaoSupport {
//SQL 관련 명령어
//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_INSERT = "INSERT INTO studydb.BOARD(SEQ, TITLE, WRITER, CONTENT) "
+ "VALUES((SELECT IFNULL(MAX(SEQ), 0) + 1 FROM BOARD A), ?, ?, ?)";
// private final String BOARD_INSERT = "INSERT INTO studydb.BOARD(SEQ, TITLE, WRITER, CONTENT) "
// + "VALUES((SELECT IFNULL(MAX(SEQ), 0) + 1 FROM BOARD A), vo.getTitle(), vo.getWriter(), vo.getContent())";
// Object[] args = {vo.getTitle(), vo.getWriter(), vo.getContent()};
// jdbcTemplate.update(BOARD_INSERT, args);
private final String BOARD_UPDATE = "UPDATE studydb.BOARD SET TITLE = ?, CONTENT = ? WHERE SEQ = ?";
private final String BOARD_DELETE = "DELETE FROM studydb.BOARD WHERE SEQ = ?";
private final String BOARD_GET = "SELECT * FROM studydb.BOARD WHERE SEQ = ?";
private final String BOARD_LIST = "SELECT * FROM studydb.BOARD ORDER BY SEQ DESC";
@Autowired
public void setSuperDataSource(DataSource dataSource) {
super.setDataSource(dataSource);
}
//CRUD 기능의 메소드 구현
//글 등록
public void insertBoard(BoardVO vo) {
System.out.println("====> JDBC로 insertBoard() 기능 처리");
getJdbcTemplate().update(BOARD_INSERT, vo.getTitle(), vo.getWriter(), vo.getContent());
}
//글 수정
public void upadateBoard(BoardVO vo) {
System.out.println("====> JDBC로 upadateBoard() 기능 처리");
getJdbcTemplate().update(BOARD_UPDATE, vo.getTitle(), vo.getWriter(), vo.getContent());
}
//글 삭제
public void deleteBoard(BoardVO vo) {
System.out.println("====> JDBC로 deleteBoard() 기능 처리");
getJdbcTemplate().update(BOARD_DELETE, vo.getTitle(), vo.getWriter(), vo.getContent());
}
//글 상세 조회
public BoardVO getBoard(BoardVO vo) {
System.out.println("====> JDBC로 getBoard() 기능 처리");
Object[] args = {vo.getSeq()};
return getJdbcTemplate().queryForObject(BOARD_GET, args, new BoardRowMapper());
}
//글 목록 조회
public List<BoardVO> getBoardList(BoardVO vo) {
System.out.println("====> JDBC로 getBoard() 기능 처리");
return getJdbcTemplate().query(BOARD_LIST, new BoardRowMapper());
}
}
- 문제는 getJdbcTemplate() 메소드가 JdbcTemplate 객체를 리턴하려면 DataSource 객체를 가지고 있어야 한다.
- 따라서 아래와 같이 반드시 부모 클래스인 JdbcDaoSupport 클래스의 setDataSource() 메소드를 호출하여 데이터소스 객체를 의존성 주입해야함
- 메소드 위에 @Autowired를 붙이면 스프링 컨테이너가 해당 메소드를 자동으로 호출해주며 메소드 매개변수 타입을 확인하여 해당 타입 객체가 존재하면 그 객체를 인자로 넘겨줌
@Autowired
public void setSuperDataSource(DataSource dataSource) {
super.setDataSource(dataSource);
}
2) 실행 결과
2. 두 번째 방법 : JdbcTemplate 클래스 <bean> 등록, 의존성 주입 ( _049_BoardWeb_JDBC_jdbcTemplate )
1) <bean> 등록하고 의존성 주입 처리
- 일반적으로 이 방법을 사용한다.
- 반드시 JdbcTemplate 객체에 DataSource 객체를 의존성 주입해야 함
<!-- DataSource 설정 -->
<!-- 외부 properties 파일 참조 -->
<context:property-placeholder location="classpath:config/datasource.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!-- MySQL -->
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<proper
2) BoardDAOSpring
- 그리고 나서 DAO 클래스에서는 @Autowired 어노테이션을 이용하여 JdbcTemplate 타입의 객체를 의존성 주입 처리하면 된다.
- JdbcDaoSupport 클래스 상속 방법보다 좀 더 깔끔한 것을 확인할 수 있음
package com.springbook.biz.board.impl;
import java.util.List;
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;
@Repository("boardDAO")
public class BoardDAOSpring {
@Autowired
private JdbcTemplate jdbcTemplate;
//SQL 관련 명령어
private final String BOARD_INSERT = "INSERT INTO BOARD(SEQ, TITLE, WRITER, CONTENT) "
+ "VALUES((SELECT IFNULL(MAX(SEQ), 0) + 1 FROM BOARD A), ?, ?, ?)";
// private final String BOARD_INSERT = "INSERT INTO studydb.BOARD(SEQ, TITLE, WRITER, CONTENT) "
// + "VALUES((SELECT IFNULL(MAX(SEQ), 0) + 1 FROM BOARD A), ?, ?, ?)";
// private final String BOARD_INSERT = "INSERT INTO studydb.BOARD(SEQ, TITLE, WRITER, CONTENT) "
// + "VALUES((SELECT IFNULL(MAX(SEQ), 0) + 1 FROM BOARD A), vo.getTitle(), vo.getWriter(), vo.getContent())";
// Object[] args = {vo.getTitle(), vo.getWriter(), vo.getContent()};
// jdbcTemplate.update(BOARD_INSERT, args);
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";
//CRUD 기능의 메소드 구현
//글 등록
//getJdbcTemplate() : JdbcTemplate객체를 리턴. JdbcDaoSupport 클래스에서 상속받아 사용하는 메소드
public void insertBoard(BoardVO vo) {
System.out.println("====> JDBC로 insertBoard() 기능 처리");
jdbcTemplate.update(BOARD_INSERT, vo.getTitle(), vo.getWriter(), vo.getContent());
}
//글 수정
public void upadateBoard(BoardVO vo) {
System.out.println("====> JDBC로 upadateBoard() 기능 처리");
jdbcTemplate.update(BOARD_UPDATE, vo.getTitle(), vo.getContent(), vo.getSeq());
}
//글 삭제
public void deleteBoard(BoardVO vo) {
System.out.println("====> JDBC로 deleteBoard() 기능 처리");
jdbcTemplate.update(BOARD_DELETE, vo.getSeq());
}
//글 상세 조회
public BoardVO getBoard(BoardVO vo) {
System.out.println("====> JDBC로 getBoard() 기능 처리");
Object[] args = {vo.getSeq()};
return jdbcTemplate.queryForObject(BOARD_GET, args, new BoardRowMapper());
}
//글 목록 조회
public List<BoardVO> getBoardList(BoardVO vo) {
System.out.println("====> JDBC로 getBoard() 기능 처리");
return jdbcTemplate.query(BOARD_LIST, new BoardRowMapper());
}
}
3) BoardServiceImpl
- JdbcTemplate 객체를 이용하여 BoardDAOSpring 클래스를 구현했으니 이제 BoardServiceImpl 클래스가 BoardDAOSpring 객체를 이용하여 DB 연동을 처리하도록 수정해줄것
- 앞에서 작성했던 BoardDAO를 BoardDAOSpring으로만 수정하면 된다.
@Service("boardService")
public class BoardServiceImpl implements BoardService{
@Autowired
// BoardDAO boardDAO;
private BoardDAOSpring boardDAO;
public void insertBoard(BoardVO vo) {
boardDAO.insertBoard(vo);
}
}
4) 실행 결과
- 기존의 JDBC 기반으로 동작했던 BoardDAO가 아닌 스프링 JDBC 기반의 BoardDAOSpring으로 DB 연동이 처리된다는 점만 다를 뿐 실행 결과는 같음
댓글