mvc란?
- mvc는 모델(model), 뷰(view), 컨트롤러(controller)의 약자로 소프트웨어를 개발하는 방법의 일종이다.
- 모델2는 모델1과 달리 jsp에서 뷰와 컨트롤러를 모두 구현하지 않고 jsp는 오직 뷰만 담당한다. 처음엔 개발하기 조금 더 복잡하지만 이후에 유지보수가 더 용이하다는 장점이 있다.
지금 하려는건 답변형 게시판 만들기이다.
0. 작업설정
먼저 데이터베이스 세팅을 해야한다. (오라클을 사용했다)
이런식으로 테이블을 생성했고, NUM컬럼은 1씩 증가하는 시퀀스를 주었다.
여기서 REF, RE_STEP, RE_LEVEL이 어떤 컬럼을 뜻하냐면,
REF > 글그룹(답변글을 포함해서 모두 같은 숫자이다)
RE_STEP > 글 스텝(몇번째 답변글인지. 예를들어 부모글이 1이라면 답변글은 2이다. 답변글의 답변글은 3이다),
RE_LEVEL > 글 순서(부모글을 제외한 나머지 글은 1씩 증가해야한다)
결국, REF는 숫자가 큰 순서대로 위로 온다. 내림차순이다.
반면, RE_STEP과 RE_LEVEL은 오름차순으로 정렬되어야 우리가 게시판에서 보는 그러한 정렬이 된다.
나는 Board라는 Dynamic Web project를 생성했다.(생성 후 build path로 servelt API 추가하는것 잊지말기)
웹프로젝트 생성하면 데이터베이스와 연동될 수 있도록 server.xml에서 커넥션 풀을 설정해주어야한다.
(커넥션 풀 설정은 후에 따로 포스팅할것이다!)
그리고 src의 lib폴더에 복사해서 넣어줘야할 파일들이 여럿이 있다.
(나는 톰캣10을 쓰므로 톰캣10 기준이다)
1. BoardDAO클래스 생성
-DAO클래스는 쿼리문을 사용하여 DB와 연결해서 필요한 데이터를 이용해 우리가 필요한 기능(메소드)를 생성하는 클래스다. 전체 DAO클래스 코드를 넣었다.
package model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Vector;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class BoardDAO {
Connection con;
PreparedStatement pstmt;
ResultSet rs;
//데이터 베이스에 연결 메소드
public void getCon() {
try {
Context initctx= new InitialContext();
Context envctx = (Context)initctx.lookup("java:comp/env");
DataSource ds = (DataSource)envctx.lookup("jdbc/oracle");
con = ds.getConnection();//커넥션 연결 해주는 메소드
}catch(Exception e) {
e.printStackTrace();
}
}
//전체 게시글의 갯수를 리턴하는 메소드
public int getAllCount(){
int count = 0; //카운트 초기화
getCon();//데이터베이스 연결
try {
//쿼리 준비
String sql ="select count(*) from board";
pstmt =con.prepareStatement(sql);
//쿼리 실행후 결과 리턴
rs = pstmt.executeQuery();
if(rs.next()){ //단일행 함수라서 while안써도 됨 //데이터가 있다면~
count = rs.getInt(1);//첫번째 결과값을 int형으로 count변수에 집어넣으란 것.
}
con.close();
}catch(Exception e) {
e.printStackTrace();
}
return count;
}
//모든 화면에 보여질 데이터 10개씩 추출해서 리턴하는 매소드
public Vector<BoardBean> getAllBoard(int startRow , int endRow){
Vector<BoardBean> v = new Vector<>(); //가방의 이름은 보드빈
getCon(); //디비연결
try {
//쿼리 준비
String SQL = "select * from (select A.* ,Rownum Rnum from (select *from board order by ref desc, re_step asc)A)"
+ "where Rnum >= ? and Rnum <= ?";
//쿼리실행 객체 선언
pstmt = con.prepareStatement(SQL);
//?에 값을 대입
pstmt.setInt(1,startRow);
pstmt.setInt(2,endRow);
//쿼리를 실행후 결과를 저장
rs = pstmt.executeQuery();
//데이터 개수가 몇개인지 모르기에 반복문을 이용하여 데이터를 추출
while(rs.next()){
//데이터를 패키징(가방 = Boardbean클래스를 이용)해줌
BoardBean bean = new BoardBean();
bean.setNum(rs.getInt(1));
bean.setWrite(rs.getString(2));
bean.setEmail(rs.getString(3));
bean.setSubject(rs.getString(4));
bean.setPassword(rs.getString(5));
bean.setReg_date(rs.getDate(6).toString());
bean.setRef(rs.getInt(7));
bean.setRe_step(rs.getInt(8));
bean.setRe_level(rs.getInt(9));
bean.setReadcount(rs.getInt(10));
bean.setContent(rs.getString(11));
//패키징한 데이터를 벡터에 저장
v.add(bean);
}
con.close();
}catch(Exception e) {
e.printStackTrace();
}
return v;
}
//하나의 게시글을 저장하는 메소드 호출
public void insertBoard(BoardBean bean) {
getCon();
int ref=0;
int re_step=1; //새글이기에
int re_level=1; //새글
try {
String refsql = "select max(ref) from board";
pstmt= con.prepareStatement(refsql);
//쿼리 실행후 결과를 리턴
rs = pstmt.executeQuery();
if(rs.next()) {
ref = rs.getInt(1)+1; //가장 큰 값에 1을 더해줌 그래야 다음번 ref값이 겹치지 않게 들어가니..
}
//데이터를 삽입하는 쿼리
String sql = "insert into board values (board_seq.nextval, ?,?,?,?,sysdate,?,?,?,0,?)";
pstmt=con.prepareStatement(sql);
pstmt.setString(1, bean.getWrite());
pstmt.setString(2, bean.getEmail());
pstmt.setString(3, bean.getSubject());
pstmt.setString(4, bean.getPassword());
pstmt.setInt(5,ref);
pstmt.setInt(6,re_step);
pstmt.setInt(7,re_level);
pstmt.setString(8,bean.getContent());
//쿼리실행
pstmt.executeUpdate();
//자원반납
con.close();
}catch (Exception e) {
e.printStackTrace();
}
}
//BoardInfo 하나의 게시글 리턴하는 메소드 //BoardBean타입으로 리턴값
public BoardBean getOneBoard(int num){
//리턴 타입 선언
BoardBean bean = new BoardBean();
getCon();
try {
//조회수 증가 쿼리 //하나의 게시글을 읽엇다는 조회수 증가
String readsql = "update board set readcount = readcount+1 where num=?";
pstmt = con.prepareStatement(readsql);
pstmt.setInt(1,num);
pstmt.executeUpdate();
//한 게시글에 대한 정보를 리턴해주는 쿼리준비
String SQL = "select * from board where num=?";
//쿼리실행객체
//쿼리실행 객체
pstmt = con.prepareStatement(SQL);
pstmt.setInt(1,num);
//쿼리 실행후 결과를 리턴
rs= pstmt.executeQuery();
if(rs.next()) { //하나의 게시글이 존재 한다면
bean.setNum(rs.getInt(1));
bean.setWrite(rs.getString(2));
bean.setEmail(rs.getString(3));
bean.setSubject(rs.getString(4));
bean.setPassword(rs.getString(5));
bean.setReg_date(rs.getDate(6).toString());
bean.setRef(rs.getInt(7));
bean.setRe_step(rs.getInt(8));
bean.setRe_level(rs.getInt(9));
bean.setReadcount(rs.getInt(10));
bean.setContent(rs.getString(11));
}
con.close();
}catch(Exception e) {
e.printStackTrace();
}
return bean;
}
//답변글이 저장되는 메소드
public void reWriteBoard(BoardBean bean){
//부모글 그룹과 글레벨 글 스템을 읽어드림
int ref =bean.getRef();
int re_step = bean.getRe_step();
int re_level = bean.getRe_level();
getCon();
try {
/////////////////////핵심 코드 ////////////////////////
//부모글 보다 큰 re_level의 값을 전부 1씩 증가시켜줌
String levelsql = "update board set re_level=re_level+1 where ref=? and re_level > ?";
//쿼리 삽입 객체 선언
pstmt = con.prepareStatement(levelsql);
pstmt.setInt(1 , ref);
pstmt.setInt(2 , re_level);
//쿼리 실행
pstmt.executeUpdate();
//답변글 데이터를 저장
String sql ="insert into board values(board_seq.NEXTVAL,?,?,?,?,sysdate,?,?,?,0,?)";
pstmt = con.prepareStatement(sql);
//?에 값을 대입
pstmt.setString(1, bean.getWrite());
pstmt.setString(2, bean.getEmail());
pstmt.setString(3, bean.getSubject());
pstmt.setString(4, bean.getPassword());
pstmt.setInt(5, ref);//부모의 ref 값을 넣어줌
pstmt.setInt(6, re_step+1);//답글이기에 부모글 re_stop에 1을 넣어줌
pstmt.setInt(7, re_level + 1);
pstmt.setString(8, bean.getContent());
//쿼리를 실행하시오
pstmt.executeUpdate();
con.close();
}catch(Exception e){
e.printStackTrace();
}
}
//Boardupdate용 Delete시 하나의 게시글을 리턴
public BoardBean getOneUpdateBoard(int num){
//리턴 타입 선언
BoardBean bean = new BoardBean();
getCon();
try {
//쿼리준비
String SQL = "select * from board where num=?";
//쿼리실행객체
//쿼리실행 객체
pstmt = con.prepareStatement(SQL);
pstmt.setInt(1,num);
//쿼리 실행후 결과를 리턴
rs= pstmt.executeQuery();
if(rs.next()) {
bean.setNum(rs.getInt(1));
bean.setWrite(rs.getString(2));
bean.setEmail(rs.getString(3));
bean.setSubject(rs.getString(4));
bean.setPassword(rs.getString(5));
bean.setReg_date(rs.getDate(6).toString());
bean.setRef(rs.getInt(7));
bean.setRe_step(rs.getInt(8));
bean.setRe_level(rs.getInt(9));
bean.setReadcount(rs.getInt(10));
bean.setContent(rs.getString(11));
}
con.close();
}catch(Exception e) {
e.printStackTrace();
}
return bean;
}
//하나의 게시글을 수정하는 메소드
public void updateBoard(int num ,String subject , String content){
getCon();
try {
//쿼리 준비
String sql = "update board set subject=? , content= ? where num = ?";
//쿼리 실행할 객체 선언
pstmt = con.prepareStatement(sql);
//?에 값을 대입 하기
pstmt.setString(1,subject);
pstmt.setString(2,content);
pstmt.setInt(3,num);
//쿼리 실행후 결과를 리턴
pstmt.executeUpdate();
//자원 반납
con.close();
}catch(Exception e) {
e.printStackTrace();
}
}
//하나의 게시글을 삭제하는 매소드
public void deleteBoard(int num){
getCon();
try {
//쿼리 준비
String sql = "delete from board where num=?";
//쿼리 실행할 객체 선언
pstmt = con.prepareStatement(sql);
//?
pstmt.setInt(1,num);
//쿼리 실행
pstmt.executeUpdate();
//자원 반납
con.close();
}catch(Exception e) {
e.printStackTrace();
}
}
}
'Language > JAVA' 카테고리의 다른 글
StringTokenizer 클래스 (0) | 2023.07.07 |
---|---|
API_3. String 클래스 (0) | 2023.07.06 |
API_2. java.util패키지의 Objects 클래스 (0) | 2023.07.06 |
API_1. Object 클래스와 메소드 (0) | 2023.07.06 |
JAVA API 클래스 - 1 (0) | 2023.07.06 |