👇 공부한 자료들의 실제 소스파일들을 기록해논 공간입니다 👇
DB를 연결한 게시판만들기 실습 - 코드작성 가이드
시작에 앞서 연결하는 것을 아직 모르신다면 이전 포스팅을 참고해 주세요
https://yurizzy.tistory.com/entry/20231107-✨-CRUD를-위한-첫걸음
만들어본 적 없는 내가. 갑자기 만들어라! 명령하신다면 당황스럽다
하지만 우리의 선생님은 가이드를 주셨다
1. 프로젝트 생성
2. 패키지 생성
3. main Class 생성
4. 관리 Class생성
5. 생성자에서 메뉴 선택하기 기능 구현
6. 객체를 실어다 나르는 용도로 이용, 객체에 대한 추상화 정의를 같이하는 객체 정의(DTO), getter&setter
7. DB준비 Table 정의 및 생성
8. 드라이버 로드 - 1번만 하면 되기 때문에 가장 적당한 위치를 잡는 게 효율적이다(객체가 생성될 때 딱 한번 실행하는 생성자에서 코딩)
9. 커넥션 자원 얻기(작업 수행 시마다 한다)
10. DAO Class 생성
11. 기능별 쿼리 만들어놓기
12. DAO class에서 기능별 메서드와 쿼리 매칭시키기
13. 쿼리전송
14. 쿼리 결괏값 리턴 받기 < INSERT, DELETE, UPDATE는 리턴값 int , SELETE는 객체 한 개 이상
15. 리턴 값 처리
16. 2개의 자원 반납하기
실습 - 그리고 미니 과제
프로그램 개발
조별로 기능을 선택하여 개발하세요.. 제출시간 8교시까지
상품문의 게시판
1. 상품 문의 글은 제목 내용 작성자 비밀글 체크, 비밀번호가 있다.
2. 문의를 등록하는 절차는 제목, 내용, 작성자, 비밀번호를 입력, 비밀글 체크를 한다.
3. 문의를 수정할 때는 제목을 검색 한 후 이전에 작성한 내용을 보여주고
수정할 수 있도록 한다. 수정은 내용만 할 수 있다.
4. 문의를 삭제할때는 제목으로 삭제하도록 한다.
5. 문의는 전체보기는 모든 글을 볼 수 있다.
6. 문의글 검색, 제목으로 검색할 수 있다. 이때 검색어가 포함되면 검색해 준다.
업그레이드 1
1. 문의글 등록시 2건 까지 등록이 가능하도록
2. 체크 하는 기능을 둔다.
3. 전체보기 기능에서 비밀글은 제목이 비밀글입니다 라고 표시한다.
4. 수정과 삭제시 글 작성시 입력한 비밀번호를 입력 받은 후 진행한다.
이번에 새롭게 조가 바뀌면서 인원은 총 3명
고민했다. 어떤 식으로 해야 좋은지
우선 3명이서 패키지명, 클래스명, 멤버변수명, 메서드명을 통일화하기로 하였다.
그래야 코드를 작성 후 합치거나 상의할 때 편할 것 같았다.
그래서 대략적으로 먼저 조율하고 클래스다이어그램을 그려보기 시작했다
Package : boardDTO
Class : BoardDTO
멤버변수 : titles
멤버변수 : content
멤버변수 : author
멤버변수 : password
멤버변수 : int checkSecret // 0이면 전체보기가능 1이면 비밀글
Package : boardDAO
Class : BoardDAO
멤버변수 : ArrayList<BoardDTO> postList = null;
멤버변수 : private String url = "jdbc:oracle:thin:@localhost:1521:orcl";
멤버변수 : private String username = "system";
멤버변수 : private String pass = "1111";
멤버변수 : private Connection conn = null; // 데이터베이스에 접속하기 위한 자원.
메서드 : boolean getConnect ()
메서드명 : createPost / 글 작성
메서드명 : editPost / 글 수정
메서드명 : deletePost / 글 삭제
메서드명 : postSearch / 글 검색
메서드명 : viewAll / 전체보기
메서드명 : prtInfo / 메뉴 숫자 및 출력 메서드
생성자 : BoardDAO() // 드라이버 로드
try { // 실행중에 발생하는 예외를 처리하여 프로그램 오류가 나지 않게 한다.
Class.forName("oracle.jdbc.driver.OracleDriver"); // - 가
ystem.out.println("드라이버 로드 성공"); // 가 코드가 정상적이면 실행된다.
} catch (Exception e) {
System.out.println("드라이버 로드 실패"); // 가 코드에서 드라이버를 로드못하면 실행
Pakage : boardView
Class : Info
메서드명 : createPost / 글 작성
메서드명 : cditPost / 글 수정
메서드명 : deletePost / 글 삭제
메서드명 : postSearch / 글 검색
메서드명 : viewAll / 전체보기
메서드명 : prtInfo / 메뉴 숫자 및 출력 메서드
기능별 시나리오
1. 게시글 작성 시나리오
작성자
-- 동일명의 작성자는 게시글 총2개이상은 불가하다
제목
내용
비밀번호
비밀글체크
-- 비밀글 체크를 하여 검색시 내용을 비밀글 로 설정되어 보이지 않게 처리하는걸 고려해야한다
2. 문의 수정 시나리오
제목 검색
비밀번호 입력 및 일치 여부 확인
이전 작성 내용 확인
수정 진행 , 내용만 수정 가능
3. 문의 삭제 시나리오
제목 검색
비밀번호 입력
삭제 할 것인지 한번더 확인
삭제 선택시 삭제 완료 출력
취소 선택시 메뉴선택 화면으로 돌아가기
4. 전체 보기 시나리오
전체 리스트를 보여주되 비밀글은 비밀글 입니다 라고 보여준다
5. 문의글 검색(키워드) 시나리오
검색은 제목으로 검색한다
해당 입력된 문장이 포함된 제목을 모두 포함하여 검색해준다
Class Diagram
CREATE TABLE board(
author varchar2(20),
title varchar2(20),
content varchar2(500),
password varchar2(20),
checkSecreat int CHECK(checkSecreat in('0', '1'))
);
소스코드
package Main;
import boardView.Info;
public class Main {
public static void main(String[] args) {
// todo : 문의 게시판 만들기
new Info();
}
}
package Functoins;
import java.util.Scanner;
public class Functions {
public String retrunText(String text) {
Scanner in = new Scanner(System.in);
System.out.print("\t" + text + " 입력 >> ");
return in.nextLine();
}
}
package boardView;
import Functoins.Functions;
import boardDAO.BoardDAO;
import boardDTO.BoardDTO;
import java.util.ArrayList;
public class Info {
private Functions fn = new Functions();
private ArrayList<BoardDTO> postList = null;
BoardDTO board = null;
public Info() {
boolean flag = true;
while (flag) {
prtInfo();
int selnum = Integer.parseInt(fn.retrunText("번호"));
switch (selnum) {
case 1: // 글 작성
createPost();
break;
case 2: // 글 수정
editPost();
break;
case 3: // 글 삭제
deletePost();
break;
case 4: // 글 검색
postSearch();
break;
case 5: // 전체보기
viewAll();
break;
case 6: // 프로그램 종료
System.out.println("프로그램을 종료합니다");
flag = false;
break;
default:
System.out.println("잘못 된 입력 번호 입니다 다시 입력하세요");
}
}
}
// 게시글 전체보기입니다
private void viewAll() {
// 전체 보기 리스트 입니다
try {
this.postList = BoardDAO.getPostList("전체보기", 5);
String check = "";
if (postList.size() != 0) {
for (BoardDTO boardDTO : postList) {
if (boardDTO.getCheckSecret() == 1) check = "비밀글";
else check = "자유글";
System.out.println("=================================");
System.out.println(String.format("%10s", "작 성 자 : ") + String.format("%-30s", boardDTO.getAuthor()));
System.out.println(String.format("%10s", "제 목 : ") + String.format("%-30s", boardDTO.getTitles()));
if (check.equals("비밀글"))
System.out.println(String.format("%10s", "내 용 : ") + String.format("%-30s", check));
else
System.out.println(String.format("%10s", "내 용 : ") + String.format("%-30s", boardDTO.getContent()));
System.out.println(String.format("%10s", "공개 여부 : ") + String.format("%-30s", check));
}
}
} catch (Exception e) {
System.out.println("예외 발생");
} finally {
System.out.println("초기화면으로 넘어갑니다");
}
}
// 게시글 조회 / Like를 이용하여 제목에 키워드로 검색하기
private void postSearch() {
System.out.println("게시글 검색 입니다 , 작성자와 글 내용 중 키워드를 입력하면 됩니다");
try {
String keyword = fn.retrunText("검색 키워드");
this.postList = BoardDAO.getPostList(keyword, 4);
String check = "";
if (postList.size() != 0) {
for (BoardDTO boardDTO : postList) {
if (boardDTO.getCheckSecret() == 1) check = "비밀글";
else check = "자유글";
System.out.println("=================================");
System.out.println(String.format("%10s", "작 성 자 : ") + String.format("%-30s", boardDTO.getAuthor()));
System.out.println(String.format("%10s", "제 목 : ") + String.format("%-30s", boardDTO.getTitles()));
if (check.equals("비밀글"))
System.out.println(String.format("%10s", "내 용 : ") + String.format("%-30s", check));
else
System.out.println(String.format("%10s", "내 용 : ") + String.format("%-30s", boardDTO.getContent()));
System.out.println(String.format("%10s", "공개 여부 : ") + String.format("%-30s", check));
}
}
} catch (Exception e) {
System.out.println("예외 발생");
} finally {
System.out.println("초기화면으로 넘어갑니다");
}
}
// 글 삭제 기능
private void deletePost() {
try {
System.out.println("게시글 수정 메뉴 입니다");
String title = fn.retrunText("검색 제목");
board = BoardDAO.postSearch(title);
int cnt = 0;
while (cnt <= 5) {
String tmpPass = fn.retrunText("비밀번호");
if (board.getPassword().equals(tmpPass)) {
System.out.println(board.getTitles() + "삭제 하시겠습니까 ?");
int selnum = Integer.parseInt(fn.retrunText("삭제 1번 , 취소 2번"));
if (selnum == 1) BoardDAO.delete(board);
else System.out.println(board.getTitles() + "삭제 취소");
break;
} else {
cnt++;
System.out.println("다시 입력하세요 [ 시도 횟수 " + cnt + "/ 5 ]");
}
}
} catch (Exception e) {
System.out.println("예외 발생");
} finally {
System.out.println("초기화면으로 넘어갑니다");
}
}
// 게시글 수정
private void editPost() {
System.out.println("게시글 수정 메뉴 입니다");
try {
String title = fn.retrunText("검색 제목");
board = BoardDAO.postSearch(title);
int cnt = 0;
while (cnt <= 3) {
String tmpPass = fn.retrunText("비밀번호");
if (board.getPassword().equals(tmpPass)) {
System.out.println("기존 내용 입니다");
System.out.println(board.getContent());
board.setContent(fn.retrunText("변경할 내용"));
BoardDAO.update(board);
break;
} else {
cnt++;
System.out.println("다시 입력하세요 [ 시도 횟수 " + cnt + "/ 3 ]");
}
}
} catch (Exception e) {
System.out.println("예외 발생");
} finally {
System.out.println("초기화면으로 넘어갑니다");
}
}
// 게시글 작성
// 작성 로직 : 작성자 / 제목 / 내용 / 비밀번호 / 비밀글체크
private void createPost() {
System.out.println("게시글 작성 메뉴 입니다");
try {
BoardDTO board = new BoardDTO();
while (true) {
if (board.setAuthor(fn.retrunText("작성자"))) {
board.setTitles(fn.retrunText("제목"));
board.setContent(fn.retrunText("내용"));
board.setPassword(fn.retrunText("비밀번호"));
if (board.setCheckSecret(Integer.parseInt(fn.retrunText("비밀글 체크( 0 : 전체글 , 1 : 비밀게시 )")))) {
BoardDAO.createPost(board);
break;
}
} else System.out.println("다시 입력하세요");
}
} catch (Exception e) {
System.out.println("예외 발생");
} finally {
System.out.println("초기화면으로 넘어갑니다");
}
}
// 메뉴 출력
private void prtInfo() {
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. 프로그램 종료 ");
}
}
package boardDTO;
import boardDAO.BoardDAO;
public class BoardDTO {
// 게시 글의 정의
// 제목
private String titles = null;
// 내용
private String content = null;
// 작성자
private String author = null;
//비밀번호
private String password = null;
// 비밀글 여부
private int checkSecret = 0;
public String getTitles() {
return titles;
}
public void setTitles(String titles) {
this.titles = titles;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getAuthor() {
return author;
}
public boolean setAuthor(String author) {
if(BoardDAO.isAuthorCnt(author)) {
this.author = author;
return true;
}
else System.out.println("작성자 별 게시글 작성은 최대 2번까지 입니다");
return false;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getCheckSecret() {
return checkSecret;
}
// 0 이면 전체보기 1 이면 비밀글
public boolean setCheckSecret(int checkSecret) {
if ( checkSecret == 1 || checkSecret == 0 ) {
this.checkSecret = checkSecret;
return true;
}
else System.out.println("번호 오류 처음부터 다시 입력합니다");
return false;
}
}
package boardDAO;
import boardDTO.BoardDTO;
import java.sql.*;
import java.util.ArrayList;
public class BoardDAO {
private static ArrayList<BoardDTO> postList = null;
private static String url = "jdbc:oracle:thin:@localhost:1521:XE";
private static String username = "system";
private static String pass = "oracle";
private static Connection conn = null;
private static PreparedStatement psmt = null;
private static ResultSet rs = null;
// 드라이버 로드
public BoardDAO() {
try {// 실행중에 발생하는 예외를 처리하여 프로그램 오류가 나지 않게 한다.
Class.forName("oracle.jdbc.driver.OracleDriver");// -가
System.out.println("드라이버 로드 성공"); // 가 코드가 정상적이면 실행
} catch (Exception e) {
System.out.println("드라이버 로드 실패");// 가 코드에서 드라이버를 로드 못하면 실행
}
}
// 커넥션 시도 리턴값 : 성공/실패
public static boolean getConnection()
{
try {
conn = DriverManager.getConnection(url, username, pass);
System.out.println("컨넥션 성공");
return true;
} catch (Exception e) {
System.out.println("컨넥션 실패");
}
return false;
}
// 글 삭제
public static void delete(BoardDTO board) {
// 쿼리문 : DELETE board WHERE title = ?;
if (getConnection()){
try {
String sql = "DELETE board WHERE title = ?";
psmt = conn.prepareStatement(sql);
psmt.setString(1, board.getTitles());
int resultInt = psmt.executeUpdate();
System.out.println( resultInt + "건 삭제 완료");
} catch (Exception e){
System.out.println("삭제 오류");
e.printStackTrace();
} finally {
resourcesReturn();
}
}
}
// 수정된 내용을 입력받고 sql 전달 메서드
public static void update(BoardDTO boardDTO){
if (getConnection()){
// 쿼리문 : UPDATE board SET content =? WHERE title =?;
try {
String sql = "UPDATE board SET content =? WHERE title =?";
psmt = conn.prepareStatement(sql);
psmt.setString(1, boardDTO.getContent());
psmt.setString(2, boardDTO.getTitles());
int resultInt = psmt.executeUpdate();
System.out.println( resultInt + "건 수정 완료");
}catch (Exception e){
System.out.println("예외 발생!");
e.printStackTrace();
}finally {
// 자원 반납 메서드 호출
resourcesReturn();
}
}
}
// 검색 메서드
public static ArrayList<BoardDTO> getPostList(String keyword, int menuNum){
postList = new ArrayList<>();
String sql = null;
if (getConnection()){
try{
if ( menuNum == 4 ){
sql = "SELECT * FROM board WHERE title LIKE ?";
psmt=conn.prepareStatement(sql);
psmt.setString(1, "%" + keyword + "%");
} else {
sql = "SELECT * FROM board";
psmt = conn.prepareStatement(sql);
}
rs=psmt.executeQuery();
while ( rs.next() ){
BoardDTO tempPost = new BoardDTO();
tempPost.setAuthor(rs.getString("author"));
tempPost.setTitles(rs.getString("title"));
tempPost.setContent(rs.getString("content"));
tempPost.setPassword(rs.getString("password"));
tempPost.setCheckSecret(rs.getInt("checkSecreat"));
postList.add(tempPost);
System.out.println(postList.size());
}
} catch (Exception e){
e.printStackTrace();
} finally {
resourcesReturn();
}
}
return postList;
}
// 검색 메서드
public static BoardDTO postSearch(String title){
// 쿼리문 : SELECT content FROM board WHERE title =?;
if (getConnection()) {
try {
String sql = "SELECT * FROM board WHERE title =?";
psmt = conn.prepareStatement(sql);
psmt.setString(1, title);
rs = psmt.executeQuery();
if ( rs.next() ){
BoardDTO board = new BoardDTO();
board.setAuthor(rs.getString("author"));
board.setTitles(rs.getString("title"));
board.setContent(rs.getString("content"));
board.setPassword(rs.getString("password"));
board.setCheckSecret(rs.getInt("checkSecreat"));
return board;
}
} catch ( Exception e ){
resourcesReturn();
}
}
return null;
}
// 게시글 새로운 글 작성시 카운트 확인
public static boolean isAuthorCnt(String author){
if (getConnection()){
try {
String sql = "SELECT COUNT(author) FROM board WHERE author = ?";
psmt = conn.prepareStatement(sql);
psmt.setString(1, author);
rs = psmt.executeQuery();
if(rs.next())
if(rs.getInt(1) < 2) return true;
} catch ( Exception e){
System.out.println("예외 발생");
} finally {
resourcesReturn();
}
}
return false;
}
// 새 게시글 작성 메서드
public static void createPost(BoardDTO board){
// 쿼리문 INSERT into board VALUES (?,?,?,?,?)
/*
CREATE TABLE board(
author varchar2(20),
title varchar2(20),
content varchar2(500),
password varchar2(20),
checkSecreat int CHECK(checkSecreat in('0', '1'))
);*/
if (getConnection()) {
try {
String sql = "INSERT into board VALUES (?,?,?,?,?)";
psmt = conn.prepareStatement(sql);
psmt.setString(1, board.getAuthor());
psmt.setString(2, board.getTitles());
psmt.setString(3, board.getContent());
psmt.setString(4, board.getPassword());
psmt.setInt(5, board.getCheckSecret());
int resultInt = psmt.executeUpdate();
System.out.println( resultInt + "건 삽입 완료 ");
} catch (SQLException e) {
System.out.println(" INSERT 오류");
throw new RuntimeException(e);
} catch (Exception e){
System.out.println(" 예외 발생 ");
e.printStackTrace();
} finally {
// 자원 반납 메서드 호출
resourcesReturn();
}
} else System.out.println("커넥션 정보 없음 ");
}
// 자원 반납 메서드정의
private static void resourcesReturn(){
try {
if ( psmt != null ) psmt.close();
if ( conn != null ) conn.close();
}catch (Exception e){
System.out.println("자원 반납에서 예외발생");
e.printStackTrace();
}
}
}
'👩🏻💻 𝐋𝐚𝐧𝐠𝐮𝐚𝐠𝐞 > ⠀⠀⠀⠀ Jᴀᴠᴀ' 카테고리의 다른 글
2023/11/09 😱 조별 프로젝트 그리고 이틀째 (0) | 2023.11.13 |
---|---|
2023/11/08 🫶 새로운 미니 프로젝트의 시작 (0) | 2023.11.13 |
2023/11/06 ✨ CRUD를 위한 첫걸음 (0) | 2023.11.07 |
2023/11/03 🐰 개인 프로젝트/자유주제 (1) | 2023.11.04 |
2023/11/02 📝 예외처리 , I/O 입출력 (1) | 2023.11.02 |