본문 바로가기
👨‍💻 2. 웹개발_Back end/2-6 Spring

[Spring] 6장 비즈니스 컴포넌트 실습 1 - 스프링 프레임워크로 글 등록 및 목록 검색 기능 프로그램 만들기 (BOARD 테이블 / 어노테이션 사용)

by 달님🌙 2021. 10. 26.
반응형

 

실습 코드 참조

 

moonhy7/SpringFramework: Spring Framework 실습 코드 정리 (github.com)

 

GitHub - moonhy7/SpringFramework: Spring Framework 실습 코드 정리

Spring Framework 실습 코드 정리. Contribute to moonhy7/SpringFramework development by creating an account on GitHub.

github.com

 

 

6.1절 BoardService 컴포넌트 구조

 

1. BoardService 컴포넌트에 대한 클래스 다이어그램 ( _022_BoardWeb_Business_Board )

 

 

2. BoardService 컴포넌트 관련 파일 작성 위치

 

6.2절 Value Object 클래스 작성

 

1. 데이터베이스 테이블 생성 쿼리

 

CREATE TABLE BOARD (
    SEQ INT PRIMARY KEY,
    TITLE VARCHAR(200),
    WRITER VARCHAR(20),
    CONTENT VARCHAR(2000),
    REGDATE DATETIME DEFAULT NOW(),
    CNT INT DEFAULT 0
);

 

2. VO 클래스

 

- VO(Value Object) 클래스는 레이어와 레이어 사이에서 관련된 데이터를 한꺼번에 주고받을 목적

- 변수 선언 후 Getter/Setter 메소드와 toString() 메소드 추가

package com.springbook.biz.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 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 + "]";
	}
}

 

 

6.3절 DAO클래스 작성

 

1. 드라이버 내려받기

 

 

 

2. JDBC Utility 클래스

 

- 모든 DAO 클래스에서 공통으로 사용할 JDBCUtil 클래스를 작성하여 Connection 획득과 해제 작업을 공통 처리

package com.springbook.biz.common;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;


public class JDBCUtil {
	public static Connection getConnection() {
		try {
			//ojdbc.jar파일에서 오라클드라이버 클래스 로딩
			Class.forName("oracle.jdbc.driver.OracleDriver");
			//MySql
			Class.forName("com.mysql.cj.jdbc.Driver");
			//오라클 DB 커넥션
//			return DriverManager.getConnection("jdbc:oracle:thin@localhost:1521:xe", "study", "study");
			//MySql 커넥션
			return DriverManager.getConnection("jdbc:mysql://localhost:3306/studydb", "study", "study");
		} catch(Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static void close(PreparedStatement 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(ResultSet rs, PreparedStatement stmt, Connection conn) {
		if(rs != null) {
			try {
				if(!rs.isClosed()) {
					rs.close();
				}
			} catch(Exception e) {
				e.printStackTrace();
			} finally {
				rs = null;
			}
		}
		
		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;
			}
		}
	}
}

 

3. DAO (Data Access Object) 클래스 작성

 

-  DAO 클래스 : 데이터베이스 연동을 담당함, DB와 연결해서 쿼리문을 보내서 결과값을 리턴받는 클래스

- @Component 대신 @Repository를 사용하는 이유 : 예외 처리에서 좀더 DAO에 적합한 기능들을 추가로 제공해줌

- BoardDAO 클래스는 BOARD 테이블과 CRUD 기능을 처리하는 역할

- 앞에서 작성한 BoardVO 객체를 매개변수와 리턴타입으로 사용하게 됨

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 updateBoard(BoardVO vo) {
		System.out.println("====> JDBC로 updateBoard() 기능 처리");
		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(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;
	}
}

 

* CRUD 기능의 메소드 이름 규칙

 

 

6.4절 Service 인터페이스 작성

 

- 인터페이스 생성 단축키 : Alt + Shift + T

package com.springbook.biz.board;

import java.util.List;

public interface BoardService {
	//CRUD 기능의 메소드 구현
	//글 등록
	void insertBoard(BoardVO vo);
	
	//글 수정
	void updateBoard(BoardVO vo);
	
	//글 삭제
	void deleteBoard(BoardVO vo);
	
	//글 상세 조회
	BoardVO getBoard(BoardVO vo);
	
	//글 목록 조회
	List<BoardVO> getBoardList(BoardVO vo);
}

 

 

6.5절 Service 구현 클래스 작성

 

- BoardServiceImpl 클래스 : BoardService 인터페이스를 구현한 클래스 (인터페이스의 모든 추상 메소드를 재정의)

- @Service("boardService") : boardService라는 이름으로 객체를 요청할 수 있게 됨

- BoardServiceImpl 클래스에서는 boardDAO라는 객체를 자동으로 생성하여 의존성 주입하고

- boardDAO에 있는 메소드들을 하나씩 호출해서 DB에 CRUD 기능을 처리해줌

- BoardServiceImpl은 데이터베이스 연동이 포함된 비즈니스 로직 처리를 위해 BoardDAO 타입의 객체를 가짐

- BoardDAO 타입의 객체를 의존성 주입하기 위해 @Autowired를 설정함

package com.springbook.biz.board.impl;

import java.util.List;

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

import com.springbook.biz.board.BoardService;
import com.springbook.biz.board.BoardVO;

@Service("boardService")
/*
 * Service 클래스는 jsp/servlet할 때 안 배웠음 
 * 업무로직 처리를 담당하는 클래스
 * ex) 계좌이체 기능 처리할 때 DB입력은 DAO에서 하게 되는데
 * DB 입력 전에 필요한 작업들(계좌 암호화, 금액 컴마 추가...) 하는 로직들을 ServiceImpl클래스에서 처리해주면 됨 
 * */
public class BoardServiceImpl implements BoardService{
	@Autowired
	BoardDAO boardDAO;
	
	public void insertBoard(BoardVO vo) {
		boardDAO.insertBoard(vo);
	}
	
	public void updateBoard(BoardVO vo) {
		boardDAO.updateBoard(vo);
	}
	
	public void deleteBoard(BoardVO vo) {
		boardDAO.deleteBoard(vo);
	}
	
	public BoardVO getBoard(BoardVO vo) {
		return boardDAO.getBoard(vo);
	}
	
	public List<BoardVO> getBoardList(BoardVO vo) {
		return boardDAO.getBoardList(vo);
	}
}

 

 

6.6절 BoardService 컴포넌트 테스트

 

1. 스프링 설정 파일 수정

 

- 컴포넌트 스캔의 범위를 com.springbook.biz 패키지로 지정

- BoardServiceImpl 클래스와 BoardDAO 클래스가 스캔 범위에 포함되므로 객체가 생성되고 의존성 주입도 처리됨

<context:component-scan base-package="com.springbook.biz"></context:component-scan>

 

2. 클라이언트 작성 및 실행

 

- 클라이언트 클래스 역할 : 스프링 컨테이너를 구동하고 BoardService 컴포넌트를 사용

- 글 등록 기능과 글 목록 기능 테스트

package com.springbook.biz.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. Sprig 컨테이너를 구동한다.
		AbstractApplicationContext container = new GenericXmlApplicationContext("applicationContext.xml");
		
		//2. Spring 컨테이너로부터 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. Spring 컨테이너 종료
		container.close();
	}
}

 

3. 실행 결과

 

 

 

 

반응형

댓글