2020년 11월 21일
업데이트:
BoardView.java
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import com.kh.jdbc.board.model.service.BoardService;
import com.kh.jdbc.board.model.vo.Board;
import com.kh.jdbc.board.model.vo.VBoard;
import com.kh.jdbc.view.JDBCView;
public class BoardView {
private Scanner sc = new Scanner(System.in);
private BoardService bService = new BoardService();
/**
* 게시판 메뉴
*/
public void boardMenu() {
int sel = 0;
do {
try {
System.out.println("====================================");
System.out.println("[게시판 메뉴]");
System.out.println("1. 게시글 목록 조회");
System.out.println("2. 게시글 상세 조회(게시글 번호)");
System.out.println("3. 게시글 작성");
System.out.println("4. 게시글 수정");
System.out.println("5. 게시글 삭제");
System.out.println("6. 게시글 검색(제목, 작성자, 내용, 제목+내용)");
System.out.println("0. 메인 메뉴로 돌아가기");
System.out.println("====================================");
System.out.print("메뉴 선택 : ");
sel = sc.nextInt();
sc.nextLine();
System.out.println();
switch(sel) {
case 1 : selectAllBoard(); break;
case 2 : selectBoard(); break;
case 3 : insertBoard(); break;
case 4 : updateBoard(); break;
case 5 : updateDeleteFl(); break;
case 6 : searchBoard(); break;
case 0 : System.out.println("프로그램 종료"); break;
default : System.out.println("메인 메뉴로 돌아갑니다.");
}
}catch(InputMismatchException e) {
System.out.println("숫자만 입력해 주세요.");
sel = -1;
sc.nextLine(); // 버퍼에 남아있는 잘못 된 문자 제거
}
}while(sel != 0);
}
/**
* 게시글 목록 조회 View
*/
private void selectAllBoard() {
System.out.println("[게시글 목록]");
// 카테고리명 | 글 번호 | 제목 | 작성일 | 작성자 | 조회수
try {
// 게시글 목록 조회 service 호출 후 결과를 반환받아 출력
List<VBoard> list = bService.selectAllBoard();
if(list.isEmpty()) {
System.out.println("조회 결과가 없습니다.");
} else {
System.out.printf(" %s | %s | %s | %s | %s | %s\n",
"카테고리", "글번호", "제목", "작성일", "작성자", "조회수");
for(VBoard board : list) {
System.out.printf(" %s | %d | %s | %s | %s | %d\n",
board.getCategoryNm(), board.getBoardNo(),
board.getTitle(), board.getCreateDt(),
board.getMemNm(),board.getReadCount());
}
}
}catch (Exception e) {
System.out.println("게시글 목록 조회 중 오류 발생");
e.printStackTrace();
}
}
/**
* 게시글 상세 조회 view
*/
private void selectBoard() {
System.out.println("[게시글 상세 조회]");
System.out.print("조회할 글 번호 :");
int boardNo = sc.nextInt();
sc.nextLine();
try {
VBoard board = bService.selectBoard(boardNo);
if(board == null) {
System.out.println("해당 번호의 글이 존재하지 않습니다.");
} else {
System.out.println("----------------------------------------------------------------------------");
System.out.printf("%d | [%s] %s\n",board.getBoardNo(), board.getCategoryNm(), board.getTitle());
System.out.printf("작성자 : %s | 작성일 : %s | 조회수 %d\n",board.getMemNm(), board.getCreateDt(), board.getReadCount());
System.out.println("----------------------------------------------------------------------------");
System.out.println(board.getContent());
System.out.println("----------------------------------------------------------------------------");
}
}catch (Exception e) {
System.out.println("게시글 상세 조회 중 오류 발생");
e.printStackTrace();
}
}
/**
* 게시글 등록 View
*/
private void insertBoard() {
System.out.println("[게시글 작성]");
// 카테고리
System.out.print("카테고리(1. JAVA / 2. DB / 3. JDBC) : ");
int categoryCd = sc.nextInt();
sc.nextLine();
// 제목
System.out.print("제목 : ");
String title = sc.nextLine();
// 내용
System.out.print("내용 : ");
StringBuffer sb = new StringBuffer();
// 기존 값은 16바이트 길이를 가지며 추후에 자동으로 늘었다 줄었다 함
// 입력되는 모든 내용을 저장할 객체 생성
String str = null;
// 키보드 입력을 받아 임시 저장할 변수 선언
System.out.println("------- 내용 입력(exit 작성 시 내용 입력 종료) -------");
while(true) {
str = sc.nextLine();
if(str.equals("exit")) {
// exit가 입력된 경우 반복문 종료
break;
}
sb.append(str + "\n");
// 입력된 문자열을 StringBuffer에 누적
} //end while
try {
// 카테고리 코드, 제목, 내용, 회원번호를 저장할 수 있는 Board 객체 생성
Board board = new Board(title,
sb.toString(), // == content
JDBCView.loginMember.getMemNo(),
categoryCd);
int result = bService.insertBoard(board);
if(result > 0) {
System.out.println("게시글 작성 성공!!");
} else {
System.out.println("게시글 작성 실패..");
}
} catch (Exception e) {
System.out.println("게시글 작성 중 오류 발생");
e.printStackTrace();
}
}
/**
* 게시글 수정 View
*/
private void updateBoard() {
System.out.println("[게시글 수정]");
// 게시글 번호를 입력받아 해당 글이 로그인한 회원의 글인지를 판별
//--> checkMyBoard() 라는 메소드를 만들어서 판별
int boardNo = checkMyBoard();
if(boardNo > 0) {
System.out.println("[게시글 수정]");
System.out.print("카테고리(1. JAVA / 2. DB / 3. JDBC) : ");
int categoryCd = sc.nextInt();
sc.nextLine();
System.out.print("제목 : ");
String title = sc.nextLine();
System.out.print("내용 : ");
StringBuffer sb = new StringBuffer();
String str = null;
System.out.println("------- 내용 입력(exit 작성 시 내용 입력 종료) -------");
while(true) {
str = sc.nextLine();
if(str.equals("exit")) {
break;
}
sb.append(str + "\n");
} //end while
try {
// 게시글 번호, 카테고리 번호, 제목, 내용
Board board = new Board(boardNo, title, sb.toString(), categoryCd);
int result = bService.updateBoard(board);
if(result > 0) {
System.out.println("게시글 수정 완료!!!");
} else {
System.out.println("게시글 수정 실패....");
}
} catch (Exception e) {
System.out.println("게시글 수정 과정에서 오류 발생");
e.printStackTrace();
}
}
}
/** 게시글이 로그인한 회원의 글인지 판별하는 View
* @return boardNo
*/
private int checkMyBoard() {
// 게시글 번호 입력
System.out.print("게시글 번호 입력 : ");
int boardNo = sc.nextInt();
sc.nextLine();
int result = 0; // 글이 존재하는지에 대한 판별 결과를 저장할 변수
try {
Board board = new Board();
board.setBoardNo(boardNo);
board.setMemNo(JDBCView.loginMember.getMemNo());
result = bService.checkMyBoard(board);
if(result > 0) { // 입력한 번호의 글이 로그인한 회원의 글인 경우
System.out.println("(확인 완료)");
result = boardNo;
}else {
System.out.println("자신의 글이 아니거나, 존재하지 않는 글번호 입니다.");
}
}catch (Exception e) {
System.out.println("게시글 확인 과정에서 오류 발생");
e.printStackTrace();
}
return result;
}
private void updateDeleteFl() {
System.out.println("[게시글 삭제]");
int boardNo = checkMyBoard();
int result = 0;
if (boardNo > 0) { // 입력한 번호의 글이 로그인한 회원의 글인 경우
System.out.print("다음 출력된 글자를 작성하시면 삭제됩니다. ");
String checkStr = bService.randomString();
System.out.printf("[%s]입력 : ", checkStr);
String inputStr = sc.nextLine();
try {
if (checkStr.equals(inputStr)) {
int deleteCheck = bService.updateDeleteFl(boardNo);
if (deleteCheck > 0)
System.out.println(boardNo + "번 글이 삭제되었습니다.");
else
System.out.println("삭제 실패");
} else {
System.out.println("잘못 입력하셨습니다.");
}
} catch (Exception e) {
System.out.println("삭제하는 과정에서 오류 발생");
}
}
}
/**
* 게시글 검색
*/
private void searchBoard() {
System.out.println("[게시글 검색]");
System.out.println("1. 제목 검색");
System.out.println("2. 내용 검색");
System.out.println("3. 제목+내용 검색");
System.out.println("4. 작성자 검색");
System.out.println("0. 취소");
System.out.print("선택 : ");
int sel = sc.nextInt();
sc.nextLine();
if(sel == 0) {
System.out.println("검색 취소");
} else if(sel >= 1 && sel <= 4) { // 1, 2, 3, 4번 메뉴 선택 시
System.out.print("검색어 입력 : ");
String keyword = sc.nextLine();
Map<String, Object> map = new HashMap<String, Object>();
map.put("sel", sel);
map.put("keyword", keyword);
try {
List<VBoard> list = bService.searchBoard(map);
System.out.println("=== 검색 결과 ===");
if(list.isEmpty()) {
System.out.println("조회 결과가 없습니다.");
} else {
System.out.printf(" %s | %s | %s | %s | %s | %s\n",
"카테고리", "글번호", "제목", "작성일", "작성자", "조회수");
for(VBoard board : list) {
System.out.printf(" %s | %d | %s | %s | %s | %d\n",
board.getCategoryNm(), board.getBoardNo(),
board.getTitle(), board.getCreateDt(),
board.getMemNm(),board.getReadCount());
}
}
} catch (Exception e) {
System.out.println("검색 과정에서 오류 발생");
e.printStackTrace();
}
} else { // 0, 1, 2, 3, 4를 제외한 수 입력 시
System.out.println("잘못 입력하셨습니다.");
}
}
}
BoardService.java
import static com.kh.jdbc.common.JDBCTemplate.*;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
import com.kh.jdbc.board.model.dao.BoardDAO;
import com.kh.jdbc.board.model.vo.Board;
import com.kh.jdbc.board.model.vo.VBoard;
public class BoardService {
private BoardDAO bDAO = new BoardDAO();
/**
* 게시글 목록 조회 Service
*
* @return list
* @throws Exception
*/
public List<VBoard> selectAllBoard() throws Exception {
// 커넥션 얻어오기
Connection conn = getConnection();
// DAO 메소드 호출 후 결과를 반환 받음
List<VBoard> list = bDAO.selectAllBoard(conn);
close(conn);
return list;
}
/**
* 게시글 상세 조회 Service
*
* @param boardNo
* @return Vboard
* @throws Exception
*/
public VBoard selectBoard(int boardNo) throws Exception {
Connection conn = getConnection();
VBoard vboard = bDAO.selectBoard(conn, boardNo);
// DB에서 게시글 정보를 성공적으로 조회 해왔을 때
// --> 해당 게시글의 조회수를 증가
if (vboard != null) {
// DB에서 해당 글의 조회수를 증가시킬 수 있는 DAO 메소드 호출
// --> UPDATE 수행
int result = bDAO.updateReadCount(conn, boardNo);
if (result > 0) {
commit(conn);
vboard.setReadCount(vboard.getReadCount() + 1);
} else {
rollback(conn);
}
}
close(conn);
return vboard;
}
/**
* 게시글 작성 Service
*
* @param board
* @return result
* @throws Exception
*/
public int insertBoard(Board board) throws Exception {
Connection conn = getConnection();
int result = bDAO.insertBoard(conn, board);
// 트랜잭션 처리
if (result > 0) {
commit(conn);
} else {
rollback(conn);
}
close(conn);
return result;
}
/**
* 게시글이 로그인한 회원의 글인지 판별하는 Service
*
* @param board
* @return result
* @throws Exception
*/
public int checkMyBoard(Board board) throws Exception {
Connection conn = getConnection();
int result = bDAO.checkMyBoard(conn, board);
close(conn);
return result;
}
/**
* 게시글 수정 Service
*
* @param board
* @return result
* @throws Exception
*/
public int updateBoard(Board board) throws Exception {
Connection conn = getConnection();
int result = bDAO.updateBoard(conn, board);
// 트랜잭션 처리
if (result > 0)
commit(conn);
else
rollback(conn);
close(conn);
return result;
}
public int updateDeleteFl(int boardNo) throws Exception {
Connection conn = getConnection();
int result = bDAO.updateDeleteFl(conn, boardNo);
if (result > 0)
commit(conn);
else
rollback(conn);
close(conn);
return result;
}
public String randomString() {
String str = "";
// 랜덤으로 영어 소문자 6개가 합쳐진 문자열 생성
for (int i = 0; i < 6; i++) {
char random = (char) ((Math.random() * 26) + 97);
str += random;
}
return str;
}
/**
* 게시글 검색용 Service
*
* @param map
* @return list
* @throws Exception
*/
public List<VBoard> searchBoard(Map<String, Object> map) throws Exception {
Connection conn = getConnection();
// 쿼리 조합
// 동일한 부분을 미리 작성하고, 다른 부분들을 별도로 조합
String query = "SELECT * FROM V_BOARD WHERE ";
String like = "LIKE '%" + map.get("keyword") + "%' "; // map.get("keyword") 이 부분은 동적 바인딩
switch ((int) map.get("sel")) {
// -> Map의 Value가 Object 타입이므로 알맞는 형태의 형변환(다운 캐스팅)이 필요
case 1:
query += "TITLE " + like;
break;
case 2:
query += "CONTENT " + like;
break;
case 3:
query += "TITLE " + like + "OR CONTENT " + like;
break;
case 4:
query += "MEM_NM " + like;
break;
}
query += "ORDER BY BOARD_NO DESC";
List<VBoard> list = bDAO.searchBoard(conn, query);
close(conn);
return list;
}
}
BoardDAO.java
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import com.kh.jdbc.board.model.vo.Board;
import com.kh.jdbc.board.model.vo.VBoard;
import static com.kh.jdbc.common.JDBCTemplate.*;
public class BoardDAO {
private Statement stmt = null;
private PreparedStatement pstmt = null;
private ResultSet rset = null;
private Properties prop = null;
public BoardDAO() {
try {
prop = new Properties();
prop.loadFromXML(new FileInputStream("board-query.xml"));
} catch (Exception e) {
}
}
/**
* @param conn
* @return list
* @throws Exception
*/
public List<VBoard> selectAllBoard(Connection conn) throws Exception{
List<VBoard> list = null;
try {
String query = prop.getProperty("selectAllBoard");
stmt = conn.createStatement();
//sql 수행 후 조회 결과 반환
rset = stmt.executeQuery(query);
//sql 수행 시 문제가 없었다면 조회 내용을 저장할 list 객체 생성
list = new ArrayList<VBoard>();
while(rset.next()) {
list.add(new VBoard (rset.getInt("BOARD_NO"),
rset.getString("TITLE"),
rset.getDate("CREATE_DT"),
rset.getInt("READ_COUNT"),
rset.getString("MEM_NM"),
rset.getString("CATEGORY_NM")
));
}
}finally {
close(rset);
close(stmt);
}
return list;
}
/** 게시글 상세 조회 DAO
* @param conn
* @param boardNo
* @return vboard
* @throws Exception
*/
public VBoard selectBoard(Connection conn, int boardNo) throws Exception {
VBoard vboard = null;
try {
String query = prop.getProperty("selectBoard");
pstmt = conn.prepareStatement(query);
pstmt.setInt(1, boardNo);
rset = pstmt.executeQuery();
if(rset.next()) {
vboard = new VBoard (rset.getInt("BOARD_NO"),
rset.getString("TITLE"),
rset.getString("CONTENT"),
rset.getDate("CREATE_DT"),
rset.getInt("READ_COUNT"),
rset.getString("MEM_NM"),
rset.getString("CATEGORY_NM")
);
}
} finally {
close(rset);
close(pstmt);
}
return vboard;
}
/** 게시글 조회수 증가 DAO
* @param conn
* @param boardNo
* @return result
* @throws Exception
*/
public int updateReadCount(Connection conn, int boardNo) throws Exception{
int result = 0;
try {
String query = prop.getProperty("updateReadCount");
pstmt = conn.prepareStatement(query);
pstmt.setInt(1, boardNo);
// SQL 수행 후 결과를 반환 받음
result = pstmt.executeUpdate();
} finally {
close(pstmt);
}
return result;
}
/** 게시글 작성 DAO
* @param conn
* @param board
* @return result
* @throws Exception
*/
public int insertBoard(Connection conn, Board board) throws Exception {
int result = 0; // DB 수행 결과를 저장할 변수 선언
try {
String query = prop.getProperty("insertBoard");
pstmt = conn.prepareStatement(query);
pstmt.setString(1, board.getTitle());
pstmt.setString(2, board.getContent());
pstmt.setInt(3, board.getMemNo());
pstmt.setInt(4, board.getCategoryCd());
result = pstmt.executeUpdate();
} finally {
close(pstmt);
}
return result;
}
/** 게시글이 로그인한 회원의 글인지 판별하는 DAO
* @param conn
* @param board
* @return result
* @throws Exception
*/
public int checkMyBoard(Connection conn, Board board) throws Exception{
int result = 0; // 반환 결과를 저장할 변수 선언
try {
// SQL문 작성
String query = prop.getProperty("checkMyBoard");
// SQL 수행 준비를 위한 PrepareStatement 객체 생성
pstmt = conn.prepareStatement(query);
// 위치 홀더에 값 배치
pstmt.setInt(1, board.getMemNo());
pstmt.setInt(2, board.getBoardNo());
// SQL 수행 및 결과 반환
rset = pstmt.executeQuery();
// 결과 값이 존재하는 경우 result에 값 저장
if(rset.next()) {
result = rset.getInt(1);
}
} finally{
close(rset);
close(pstmt);
}
return result;
}
/** 게시글
* @param conn
* @param board
* @return
* @throws Exception
*/
public int updateBoard(Connection conn, Board board) throws Exception {
int result = 0;
try {
String query = prop.getProperty("updateBoard");
pstmt = conn.prepareStatement(query);
pstmt.setString(1, board.getTitle());
pstmt.setString(2, board.getContent());
pstmt.setInt(3, board.getCategoryCd());
pstmt.setInt(4, board.getBoardNo());
result = pstmt.executeUpdate();
// DML 수행 시 성공한 행의 개수를 반환
// DDL 수행 성공 시 0을 반환
} finally {
close(pstmt);
}
return result;
}
public int updateDeleteFl(Connection conn, int boardNo) throws Exception{
int result = 0;
try {
String query = prop.getProperty("updateDeleteFl");
pstmt = conn.prepareStatement(query);
pstmt.setInt(1, boardNo);
result = pstmt.executeUpdate();
// DML 수행 시 성공한 행의 개수를 반환
// DDL 수행 성공 시 0을 반환
} finally {
close(pstmt);
}
return result;
}
/** 게시글 검색 DAO
* @param conn
* @param query
* @return list
* @throws Exception
*/
public List<VBoard> searchBoard(Connection conn, String query) throws Exception {
List<VBoard> list = null;
try {
// query를 Service에서 완성하여 얻어왔으므로
// 바로 Statement 객체를 생성하여 수행
stmt = conn.createStatement();
rset = stmt.executeQuery(query);
// 여러 행이 나올 가능성이 있으므로 while문 사용
list = new ArrayList<VBoard>();
while(rset.next()) {
list.add(new VBoard (rset.getInt("BOARD_NO"),
rset.getString("TITLE"),
rset.getDate("CREATE_DT"),
rset.getInt("READ_COUNT"),
rset.getString("MEM_NM"),
rset.getString("CATEGORY_NM")
));
}
} finally {
close(rset);
close(stmt);
}
return list;
}
}
board-query.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<!-- board 관련 SQL 구문을 작성하는 xml 파일 -->
<entry key="selectAllBoard">
SELECT * FROM V_BOARD
ORDER BY BOARD_NO DESC
</entry>
<entry key="selectBoard">
SELECT * FROM V_BOARD
WHERE BOARD_NO = ?
</entry>
<entry key="updateReadCount">
UPDATE TB_BOARD
SET READ_COUNT = READ_COUNT + 1
WHERE BOARD_NO = ?
</entry>
<entry key="insertBoard">
INSERT INTO TB_BOARD(BOARD_NO, TITLE, CONTENT, MEM_NO, CATEGORY_CD)
VALUES(SEQ_BNO.NEXTVAL, ?, ?, ?, ?)
</entry>
<!-- 특정 게시글이 특정 회원의 글이 맞는지 조회 -->
<entry key = "checkMyBoard">
SELECT COUNT (*) FROM TB_BOARD
WHERE MEM_NO = ?
AND BOARD_NO = ?
AND DELETE_FL = 'N'
</entry>
<entry key="updateBoard">
UPDATE TB_BOARD SET TITLE=?, CONTENT=?, CATEGORY_CD=?
WHERE BOARD_NO = ?
</entry>
<entry key="updateDeleteFl">
UPDATE TB_BOARD SET DELETE_FL = 'Y'
WHERE BOARD_NO = ?
</entry>
</properties>
댓글남기기