티스토리 뷰
우선, 기본적으로 Spring 프레임워크는 제어의 역행 구조를 가지고 있기 때문에, 다음과 같은 구조로 프로젝트가 실행된다.
이 때, 일반적인 Dynamic Web Project 였다면, Controller 가 각 엑션을 구현받은 클래스들을 호출하여 사용하지만, Spring은 이를 Controller, Service, DAO, VO 등의 객체를 Spring Container가 자동으로 생성하도록 어노테이션을 통하여 설정할 수 있다.
어노테이션 | 위치 | 의미 |
@Service | ~ServiceImpl | 해당 클래스는 비즈니스 로직을 처리하는 Service 클래스이다. |
@Repository | ~DAO | 해당 클래스는 DB 연동을 처리하는 DAO 클래스이다. |
@Controller | ~Controller | 해당 클래스는 사용자의 요청을 제어하는 Controller 클래스이다. |
간단하게 DB와 연동해서 CRUD 기능만 구현한 예제 프로젝트를 하나 보면서 이해해보자.
우선, 파일의 구조는 다음과 같다.
◎JDBCUtil.java
DB Connection 객체 관리를 위한 클래스
package com.choonham.test2.common;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class JDBCUtil {
public JDBCUtil() {
}
/** 1. 데이터베이스 접속 객체 반환 **/
public static Connection getConnection() {
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
//추후 변경 예정
String url = "jdbc:oracle:thin:@127.0.0.1:1521:XE";
return DriverManager.getConnection(url, "choonham", "6725");
} catch(Exception e){
e.printStackTrace();
}
return null;
}
/** 각 자원 해제 메서드**/
public static void close(Statement stmt, Connection conn){
if(stmt != null) {
try{
if(!stmt.isClosed()){
stmt.close();
}
} catch(Exception e){
e.printStackTrace();
} finally{
stmt = null;
}
}
if(conn != null) {
try{
if(!conn.isClosed()){
conn.close();
}
} catch(Exception e){
e.printStackTrace();
} finally{
conn = null;
}
}
}
public static void close(Statement stmt, Connection conn, ResultSet rs){
if(stmt != null) {
try{
if(!stmt.isClosed()){
stmt.close();
}
} catch(Exception e){
e.printStackTrace();
} finally{
stmt = null;
}
}
if(conn != null) {
try{
if(!conn.isClosed()){
conn.close();
}
} catch(Exception e){
e.printStackTrace();
} finally{
conn = null;
}
}
if(rs != null) {
try{
if(!rs.isClosed()){
rs.close();
}
} catch(Exception e){
e.printStackTrace();
} finally{
rs = null;
}
}
}
}
◎BoardService.java (interface)
CRUD 기능에 관련된 메서드를 가지고 있는 인터페이스이다.
package com.choonham.test2.board;
import java.util.List;
/** CRUD 에 관련된 메서드 **/
public interface BoardService {
// 글 등록
void insertBoard(BoardVO vo);
//글 수정
void updateBoard(BoardVO vo);
//글 삭제
void deleteBoard(BoardVO vo);
//글 목록
List<BoardVO> getBoardList(BoardVO vo);
//글 상세
BoardVO getBoard(BoardVO vo);
}
◎BoardVO.java
package com.choonham.test2.board;
import java.sql.Date;
public class BoardVO {
private int seq;
private String title;
private String writer;
private String content;
private Date regDate;
private int cnt;
public BoardVO() {
// TODO Auto-generated constructor stub
}
public int getSeq() {
return seq;
}
public void setSeq(int seq) {
this.seq = seq;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getRegDate() {
return regDate;
}
public void setRegDate(Date regDate) {
this.regDate = regDate;
}
public int getCnt() {
return cnt;
}
public void setCnt(int cnt) {
this.cnt = cnt;
}
@Override
public String toString() {
return "BoardVO [seq=" + seq + ", title=" + title + ", writer=" + writer + ", content=" + content + ", regDate="
+ regDate + ", cnt=" + cnt + "]";
}
}
◎BoardDAO.java
실제로 DB 연관 메서드의 기능을 작성해놓은 DAO 클래스이다. (따로 인터페이스로 구현을 하거나, 받지는 않는다.)
package com.choonham.test2.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.choonham.test2.board.BoardVO;
import com.choonham.test2.common.JDBCUtil;
/** 테이블에 데이터를 실제로 접근 **/
@Repository("boardDAO")
public class BoardDAO {
//JDBC 관련 변수
private Connection conn = null;
private PreparedStatement pstmt = 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_UPDATE = "update board set title = ?, content = ?, where seq = ?";
private final String BOARD_DELETE = "delete board where seq = ?";
private final String BOARD_GET = "select * from board where seq = ?";
private final String BOARD_LIST = "select * from order by seq desc";
//CRUD 기능의 메서드 구현
//글 등록
public void insertBoard(BoardVO vo) {
try{
conn = JDBCUtil.getConnection();
pstmt = conn.prepareStatement(BOARD_INSERT);
pstmt.setString(1, vo.getTitle());
pstmt.setString(2, vo.getWriter());
pstmt.setString(3, vo.getContent());
pstmt.executeUpdate();
} catch(Exception e) {
e.printStackTrace();
} finally{
JDBCUtil.close(pstmt, conn);
}
}
//글 수정
public void updateBoard(BoardVO vo) {
try{
conn = JDBCUtil.getConnection();
pstmt = conn.prepareStatement(BOARD_UPDATE);
pstmt.setString(1, vo.getTitle());
pstmt.setString(2, vo.getContent());
pstmt.setInt(3, vo.getSeq());
pstmt.executeUpdate();
} catch(Exception e) {
e.printStackTrace();
} finally{
JDBCUtil.close(pstmt, conn);
}
}
//글 삭제
public void deleteBoard(BoardVO vo) {
try{
conn = JDBCUtil.getConnection();
pstmt = conn.prepareStatement(BOARD_DELETE);
pstmt.setInt(1, vo.getSeq());
pstmt.executeUpdate();
} catch(Exception e) {
e.printStackTrace();
} finally{
JDBCUtil.close(pstmt, conn);
}
}
//글 목록
public List<BoardVO> getBoardList(BoardVO vo) {
List<BoardVO> boardList = new ArrayList<BoardVO>();
try{
conn = JDBCUtil.getConnection();
pstmt = conn.prepareStatement(BOARD_LIST);
rs = pstmt.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);
}
pstmt.executeUpdate();
} catch(Exception e) {
e.printStackTrace();
} finally{
JDBCUtil.close(pstmt, conn);
}
return boardList;
}
//글 상세
public BoardVO getBoard(BoardVO vo) {
BoardVO board = null;
try{
conn = JDBCUtil.getConnection();
pstmt = conn.prepareStatement(BOARD_GET);
pstmt.setInt(1, vo.getSeq());
rs = pstmt.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(pstmt, conn);
}
return board;
}
public BoardDAO() {
}
}
◎BoardServiceImpl.java
BoardService 인터페이스를 구현받아서 BoardDAO를 호출해, 관련 메서드를 실행하게끔 하는 클래스
package com.choonham.test2.board.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.choonham.test2.board.BoardService;
import com.choonham.test2.board.BoardVO;
@Service("boardService")
public class BoardServiceImpl implements BoardService{
@Autowired
private BoardDAO boardDAO;
public BoardServiceImpl() {
}
@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 List<BoardVO> getBoardList(BoardVO vo) {
return boardDAO.getBoardList(vo);
}
@Override
public BoardVO getBoard(BoardVO vo) {
return boardDAO.getBoard(vo);
}
}
◎applicationContext.xml
<?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:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
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">
<context:component-scan base-package="com.choonham.test2"></context:component-scan>
</beans>
이제 Main에서 값을 넣어주고 Insert 메서드를 시험삼아 호출해보면, 데이터가 정상적으로 DB에 삽입이 된다.
◎Main
package com.choonham.test2.board;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
public class BoardServiceClient {
public static void main(String[] args) {
AbstractApplicationContext container = new GenericXmlApplicationContext("applicationContext.xml");
BoardService boardService = (BoardService)container.getBean("boardService");
BoardVO vo = new BoardVO();
vo.setTitle("임시 제목");
vo.setWriter("춘햄");
vo.setContent("임시 내용");
boardService.insertBoard(vo);
container.close();
}
}
스프링의 전체적인 제어 구조를 한번 훑어보기 위한 예제를 풀어봤는데... 아직 직관적으로 데이터의 흐름이 보이는 단계가 아니라서, 조금 낯설다...
'[JAVA] > Spring' 카테고리의 다른 글
[Spring] Spring JDBC 2 : DAO Class 구현 (0) | 2021.06.17 |
---|---|
[Spring] Spring JDBC 1 : 사용을 위한 기본 설정 (0) | 2021.06.17 |
[Spring] bean 7 : 객체 자동 등록, component-scan (0) | 2021.06.16 |
[Spring] bean 6: Collection 맵핑 (0) | 2021.06.16 |
[Spring] bean 5: Namespace를 이용한 DI (0) | 2021.06.15 |
- redux-thunk
- 이탈리안 레스토랑
- Async
- 정보보안기사 #실기 #정리
- react-native
- AsyncStorage
- 파니노구스토
- Promise
- react
- 인천 구월동 이탈리안 맛집
- 인천 구월동 맛집
- 맛집
- redux
- await
- javascript
- Total
- Today
- Yesterday