본문 바로가기

수업내용

[Day32][JDBC] 게시판 메뉴 / 글쓰기 / 글목록 조회 / 싱글톤 패턴

 

11. 게시판

 

-- 게시판 메뉴 만들기

 

(Eclipse)MemberNBoardMainApp main method 밖

public static void boardMenu() {
	System.out.println("================== 게시판 ==================");
	System.out.println("1. 글쓰기    2. 글 목록 조회    3. 글 조회\n"
						+ "4. 글 수정   5. 글 삭제           6. 메인메뉴로 돌아가기");
	System.out.println("==========================================");
		
	System.out.print("\n▷ 게시판메뉴번호 선택 : ");
}

 

(Eclipse)MemberNBoardMainApp switch~case "11"

case "11": // 게시판
				
		String boardMenuno = "";
		outer:
		do {
		boardMenu();
		boardMenuno = sc.nextLine();
				
		switch (boardMenuno.trim()) {
		case "1": // 글쓰기
					
			break;
					
		case "2": // 글 목록 조회
					
			break;
					
		case "3": // 글 조회
	
			break;
					
		case "4": // 글 수정
					
			break;
					
		case "5": // 글 삭제
					
			break;
					
		case "6": // 메인메뉴로 돌아가기
					
			break outer;

 

(SQL)myorauser

create table jdbc_tbl_board
(no             number                      -- 글번호(sequence)
,fk_userid      varchar2(20) not null       -- 글쓴이의 ID(F.K)
,title          Nvarchar2(100) not null     -- 글제목
,contents       Nvarchar2(2000) not null    -- 글내용
,writepasswd    varchar2(20) not null       -- 글암호(글수정 또는 글 삭제시 사용되는 암호)
,readcount      number default 0            -- 글조회수(다른 사람이 내 글을 읽었을 때만 글 조회수가 1씩 증가하도록 한다.)
,writeday       date default sysdate        -- 작성일자
,status         number(1) default 1         -- 글삭제유무판단 1:게시된글 0:삭제된글
,constraint PK_jdbc_tbl_board_no primary key(no)
,constraint FK_jdbc_tbl_board_fk_userid foreign key(fk_userid) 
                                        references jdbc_tbl_member(userid)
,constraint CK_jdbc_tbl_board_status check(status in (0, 1))
);

create sequence seq_jdbc_tbl_board
start with 1
increment by 1
nomaxvalue
nominvalue
nocycle
nocache;

 


 

-- Package(jdbc.day03.board.model)에 Class(BoardDTO, BoardDAO), Interface(InterBoardDAO) 생성

-- Package(jdbc.day03.board.controller)에 Class(BoardCtrl)와 Interface(InterBoardCtrl) 생성

 

1. 글쓰기

 

(Eclipse)MemberNBoardMainApp main method 안

InterBoardCtrl boardCtrl = new BoardCtrl();

 

(Eclipse)MemberNBoardMainApp switch case "11"의 case "1"

case "1": // 글쓰기
		n = boardCtrl.boardWrite(sc, loginuser.getUserid());
		break;

 

(Eclipse)InterBoardCtrl

int boardWrite(Scanner sc, String userid);

 

(Eclipse)BoardCtrl

@Override
public int boardWrite(Scanner sc, String userid) {
	int n = 0;

	String title = "";
	String contents = "";
	String writepasswd = "";
	do {
		System.out.print("▷ 글제목 : ");
		title = sc.nextLine();

		if (!title.trim().isEmpty())
			break;
	} while (true);

	do {
		System.out.print("▷ 글내용 : ");
		contents = sc.nextLine();

		if (!contents.trim().isEmpty())
			break;
	} while (true);

	do {
		System.out.print("▷ 글암호 : ");
		writepasswd = sc.nextLine();

		if (!writepasswd.trim().isEmpty())
			break;
	} while (true);

	BoardDTO bdto = new BoardDTO();
	bdto.setFk_userid(userid);
	bdto.setTitle(title);
	bdto.setContents(contents);
	bdto.setWritepasswd(writepasswd);

	n = boardDao.boardWrite(bdto, sc);

	return n;
}

 

(Eclipse)InterBoardDAO

int boardWrite(BoardDTO bdto, Scanner sc);

 

(Eclipse)BoardDAO

 

2. 글 목록 조회

 

(Eclipse)MemberNBoardMainApp switch case "11"의 case "2"

case "2": // 글 목록 조회
	List<BoardDTO> boardList = boardCtrl.selectAllBoardTitle();
	break;

 

(Eclipse)InterBoardCtrl

List<BoardDTO> selectAllBoardTitle();

 

(Eclipse)BoardCtrl

@Override
public List<BoardDTO> selectAllBoardTitle() {
		
	List<BoardDTO> boardList = boardDao.selectAllBoardTitle();
		
	return boardList;
}

 

(Eclipse)InterBoardDAO

List<BoardDTO> selectAllBoardTitle();

 

 


 

싱글톤 패턴

 

-- 인스턴스가 사용될 때에 똑같은 인스턴스를 만들어 내는 것이 아니라, 동일 인스턴스 1개만을 사용하도록 하는 것

 

-- 소프트웨어 디자인 패턴에서 싱글턴 패턴(Singleton pattern)을 따르는 클래스는, 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다. 
이와 같은 디자인 유형을 싱글톤 패턴이라고 한다.  

 

-- 프로그램상에서 하나만 사용되어야 하는 객체를 만들때 매우 유용하다.

→ 예를 들어 동일한 커넥션 객체(Connection conn)를 만들때 사용하면 된다. Singleton 패턴을 이용하면, 하나의 커넥션 객체(Connection conn)를 만들어서 여러 DAO 에서 사용할 수 있게 된다.

 

 

-- Package(jdbc.day03.singleton.exam)와 Class(NoSingletonNumber, SingletonNumber, OrderObject, MainApp) 생성

 


-- Package(jdbc.connection)와 Class(MyDBConnection) 생성

 

(Eclipse)MyDBConnection

import java.sql.*;

public class MyDBConnection {
	
	// 1. 오라클 드라이버
	private static final String Driver = "oracle.jdbc.driver.OracleDriver";
	
	// 2. 연결할 오라클 서버의 주소(URL)
	private static final String URL = "jdbc:oracle:thin:@127.0.0.1:1521:xe";
	
	// 3. 오라클 서버에 연결할 사용자 계정명
	private static final String USER = "myorauser";
			
	// 4. 오라클 서버에 연결할 사용자 계정명의 암호
	private static final String PASSWORD = "eclass";
	
	// 5. 리턴해 줄 Connection 객체
	private static Connection conn = null;
	
	/// *** static 초기화 블럭 *** ///
	// static 초기화 블럭은 딱 1번만 호출(실행) 되어진다.
	
	static {

		// 1. 오라클 드라이버 로딩
		try {
			Class.forName(Driver);

			// 2. Connection 객체 생성
			DriverManager.getConnection(URL, USER, PASSWORD);

		} catch (ClassNotFoundException e) {
			System.out.println(">> ojdbc6.jar 파일이 없습니다. <<");
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/// *** 생성자 *** ///
	private MyDBConnection() { }
			
	/// *** Connection conn 리턴 시켜 주기 *** ///
	public static Connection getConn() {
		return conn;
	}
	
	// == Connection conn 객체 자원 반납하기 == //
	public static void closeConnection() {
		try {
			if (conn != null)
				conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
}

 

(Eclipse)BoardDAO

private Connection conn = null;
private PreparedStatement pstmt = null;
private ResultSet rs = null;
	
	// == 사용한 자원을 반납해 주는 메소드 생성하기 == //	
public void close() {
	try {
		if (rs != null)
			rs.close();
		if (pstmt != null)
			pstmt.close();
	} catch (SQLException e) {
		e.printStackTrace();
	}

}	
	
// 1. 글쓰기
@Override
public int boardWrite(BoardDTO bdto, Scanner sc) {

	int n = 0;
		
	try {
		conn = MyDBConnection.getConn();

		String sql = " insert into jdbc_tbl_board(no, fk_userid, title, contents, writepasswd, writeday) "
				+ " values(seq_tbl_board.nextval, ?, ?, ?, ?, ? ) ";

		pstmt = conn.prepareStatement(sql);
			
		pstmt.setString(1, bdto.getFk_userid());
		pstmt.setString(2, bdto.getTitle());
		pstmt.setString(3, bdto.getContents());
		pstmt.setString(4, bdto.getWritepasswd());
		pstmt.setDate(5, bdto.getWriteday());
			
		n = pstmt.executeUpdate();
		
		String yn = "";
		do {
			System.out.println(">> 글쓰기를 완료하시겠습니까? [Y/N] => ");
			yn = sc.nextLine();
				
			if(n==1 && ("Y".equals(yn) || "y".equals(yn))) {
				conn.commit();
				break;
			}
			else if(n==1 && ("N".equals(yn) || "n".equals(yn))) {
				conn.rollback();
				n = 0;
				break;
			}
			else
				System.out.println(">> Y 또는 N만 입력하세요!! \n");
					
		} while (true);
	} catch (SQLException e) {
		e.printStackTrace();
	} finally {
		close();
	}	
	return n;
}