MVC2 - (3)

2022. 10. 7. 16:30Dev.Program/Java & Spring

728x90

DAO 객체 하나를 돌려쓰기 위해서 싱글톤패턴을 사용

< BoardFrontController.java >

  • 메인 페이지를 호출하는 /Main.bo 추가해주기! (편의상)

  • 주소창 확인!

 

  • board 안보이면 오른쪽밑에 open scrapbook
  • DESC board; 에 커서 올리고 Alt + S
  • 실행창

 

< BoardDAO.java >

public int insertArticle(BoardBean boardBean) {
// Service 클래스로부터 BoardBean 객체를 전달받아 DB 에 INSERT 작업 수행
// => 수행 결과 값으로 int형 insertCount 를 리턴받아 다시 Service 클래스로 리턴
int insertCount = 0;

// DB 작업에 필요한 변수 선언(Connection 객체는 이미 외부로부터 전달받음)
PreparedStatement pstmt = null;
ResultSet rs = null;

try {
int num = 1; // 새 게시물 번호를 저장할 변수(초기값으로 초기번호 1번 설정)

// 현재 게시물의 번호 중 가장 큰 번호(최대값)를 조회하여 다음 새 글 번호 결정(+1)
String sql = "SELECT MAX(board_num) FROM board"; // 최대값 조회 쿼리문

pstmt = con.prepareStatement(sql);
rs = pstmt.executeQuery();

if (rs.next()) { // 등록된 게시물이 하나라도 존재할 경우 게시물 번호 조회 성공
// 조회된 번호 + 1 을 수행하여 새 글 번호로 저장
num = rs.getInt(1) + 1;
}
// => 만약 조회가 실패할 경우 새 글 번호는 1번이므로 기본값 num 그대로 사용

// 전달받은 데이터와 계산된 글 번호를 사용하여 INSERT 작업 수행
// => board_re_ref 는 새 글 번호, board_re_lev ,board_re_seq, board_readcount 는 0
// => 마지막 파라미터인 board_date(게시물 작성일) 값은 DB의 now() 함수를 사용하여
//    DB 서버의 시스템 현재 시각 가져오기
sql = "INSERT INTO board VALUES (?,?,?,?,?,?,?,?,?,?,now())";
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, num); // 계산된 새 글 번호 사용
pstmt.setString(2, boardBean.getBoard_name());
pstmt.setString(3, boardBean.getBoard_pass());
pstmt.setString(4, boardBean.getBoard_subject());
pstmt.setString(5, boardBean.getBoard_content());
pstmt.setString(6, boardBean.getBoard_file());
pstmt.setInt(7, num); // board_re_ref(새 글 번호 그대로 지정)
pstmt.setInt(8, 0); // board_re_lev
pstmt.setInt(9, 0); // board_re_seq
pstmt.setInt(10, 0); // board_readcount

// INSERT 구문 실행 후 리턴되는 결과값을 insertCount 변수에 저장
insertCount = pstmt.executeUpdate();

} catch (SQLException e) {
// e.printStackTrace();
System.out.println("BoardDAO - insertArticle() 실패! : " + e.getMessage());
} finally {
// DB 자원 반환
// ⇒ 주의! Connection 객체는 Service 클래스에서 별도로 사용해야하므로 닫으면 안됨!
// JdbcUtil.close(rs);
// JdbcUtil.close(pstmt);
// => static import 기능을 사용하여 db.JdbcUtil 클래스 내의 모든 static 멤버 import
close(rs);
close(pstmt);
}

return insertCount;
}
  • BoardWriteProService.java 에서 이 부분을 수행하기 위해서 finally 에서는 Connection을 닫아주면 안됨
  • < 이부분



< BoardWriteProAction.java >

System.out.println("접속 IP : " + request.getRemoteAddr());
System.out.println("글 제목 : " + multi.getParameter("board_subject"));

 

======== action 패키지에 BoardListAction.java 만들기

  • 글목록 조회를 위해!
package action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import vo.ActionForward;

public class BoardListAction implements Action {

@Override
public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("BoardListAction");

ActionForward forward = null;

return forward;
}

}
  • 여기까지가 세트! 만들때 forward 도 만들어서 리턴해두기!
  • 출력문은 이 메서드가 제대로 호출되는 지 알아보려고 적는 거!

 

< BoardFrontController.java >

  • 이제 이 부분 지우고 글 목록 조회를 위해 BoardListAction 클래스 인스턴스 생성
  • DB 로 가서 글 목록을 전부 들고와야하기 때문에 jsp 로 가는 것이 아니라 action 클래스로 감!
else if(command.equals("/BoardList.bo")) {
// 글 목록 조회를 위해 BoardListAction 클래스 인스턴스 생성
action = new BoardListAction();
// 공통 메서드인 execute() 메서드를 호출하여 request, response 객체 전달
try {
forward = action.execute(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
  • else if 수정
  • 글 등록했을 때 BoardListAction 뜸!

 

======== svc 패키지에 BoardListService.java 만들기

package svc;

public class BoardListService {

// 전체 게시물 목록 갯수 가져오기
public int getListCount() {
System.out.println("BoardListService - getListCount()");
int listCount = 0;

return listCount;
}

}

 

< BoardListAction.java >

BoardListService boardListService = new BoardListService();
int listCount = boardListService.getListCount();
  • 추가

  • 콘솔창

 

forward = new ActionForward();
forward.setPath("/board/qna_board_list.jsp");
  • 또 추가
  • dispatcher 방식이라(디폴트 false) setRedirect() 생략 함

 

586p

< BoardWriteProAction.java >

if(!isWriteSuccess) {
// System.out.println("글 등록 실패!");
// 자바스크립트를 사용하여 다이얼로그를 통해 실패메세지 출력 후 이전페이지로 이동
// 1. response 객체를 사용하여 문서 타입 및 인코딩 설정
response.setContentType("text/html;charset=UTF-8");
// 2. response 객체의 getWriter() 메서드를 호출하여
//    출력스트림 객체(PrintWriter)를 리턴받음
PrintWriter out = response.getWriter();
// 3. PrintWriter 객체의 println() 메서드를 호출하여
//    웹에서 수행할 작업(자바스크립트 출력 등)을 기술
out.println("<script>"); // 자바스크립트 시작 태그
out.println("alert('글 등록 실패!')"); // 다이얼로그 메세지 출력
out.println("history.back();"); // 이전 페이지로 돌아가기
out.println("</script>"); // 자바스크립트 끝 태그
}
  • if 문 수정!
  • 위에 테스트 용으로 false 값을 바로 준다! (글실패 확인해야하니까)

> 글쓰기 화면부터 시작

글 등록 눌렀을 때

  • 이렇게 alert 창 뜨면 잘 동작하고 있는거다.

 

587p

600p

589p

< BoardListAction.java >

@Override
public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("BoardListAction");

ActionForward forward = null;

int page = 1; // 현재 페이지 번호를 저장할 변수
int limit = 10; // 한 페이지 당 출력할 게시물 수 지정

// 파라미터로 전달받은 페이지 번호가 있을 경우 가져와서 page 변수에 저장
if(request.getParameter("page") != null) {
page = Integer.parseInt(request.getParameter("page")); // String -> int 변환
}

// BoardListService 클래스 인스턴스 생성
// 게시물 전체 갯수를 조회하기 위해 getListCount() 메서드 호출하여 갯수 리턴받기
BoardListService boardListService = new BoardListService();
int listCount = boardListService.getListCount();

// 지정한 갯수 만큼의 게시물 가져오기
// 게시물 목록 정보를 저장할 ArrayList 객체 생성 => 제네릭 타입으로 BoardBean 타입 지정
// ArrayList<BoardBean> articleList = new ArrayList<BoardBean>();

// BoardListService 클래스의 getArticleList() 메서드를 호출하여 게시물 목록 가져오기
// => 파라미터 : 현재 페이지번호(page), 한 번에 가져올 게시물 최대 갯수(limit)
// => 리턴타입 : ArrayList<BoardBean> => 게시물 1개 저장할 BoardBean 제네릭 타입으로 지정
ArrayList<BoardBean> articleList = boardListService.getArticleList(page, limit);

// ActionForward 객체를 생성하여 Dispatcher 방식으로
// 포워딩 경로를 board 폴더 내의 qna_board_list.jsp 페이지로 지정
forward = new ActionForward();
forward.setPath("/board/qna_board_list.jsp");

return forward;
}
  • 메서드 자동완성

 

< BoardListService.java >

public ArrayList<BoardBean> getArticleList(int page, int limit) {
System.out.println("BoardListService - getArticleList()");

ArrayList<BoardBean> articleList = null;

return articleList;
}
  • 껍데기만 우선 만들기! (자동완성 된 메서드)

  • 리스트 페이지를 요청했을 때
  • 뜨는지 확인하기

 

< Service 클래스 >

// DB 작업을 위한 준비 => Connection 객체, DAO 객체, DAO 객체의 메서드 호출
// 1. DB 작업에 필요한 Connection 객체 가져오기
Connection con = getConnection();

// 2. DB 작업을 위한 BoardDAO 객체 생성 => 싱글톤 패턴으로 생성된 객체 가져오기
BoardDAO boardDAO = BoardDAO.getInstance();

// 3. BoardDAO 객체에 Connection 객체 전달
boardDAO.setConnection(con);

// 4.

// 5. Connection 객체 반환
close(con);
  • 이렇게 네가지가 계속 반복!

< BoardListService.java >

public int getListCount() {
System.out.println("BoardListService - getListCount()");
int listCount = 0;

// DB 작업을 위한 준비 => Connection 객체, DAO 객체, DAO 객체의 메서드 호출
// 1. DB 작업에 필요한 Connection 객체 가져오기
Connection con = getConnection();

// 2. DB 작업을 위한 BoardDAO 객체 생성 => 싱글톤 패턴으로 생성된 객체 가져오기
BoardDAO boardDAO = BoardDAO.getInstance();

// 3. BoardDAO 객체에 Connection 객체 전달
boardDAO.setConnection(con);

// 4. BoardDAO 클래스의 selectListCount() 메서드를 호출하여 전체 게시물 수 가져오기
listCount = boardDAO.selectListCount();

// 5. Connection 객체 반환
close(con);

// 6. 작업 결과 리턴
return listCount;
}
  • 메서드 자동 완성

< BoardDAO.java >

// 전체 게시물 수 계산
public int selectListCount() {
int listCount = 0;

PreparedStatement pstmt = null;
ResultSet rs = null;

try {
// board_num 컬럼의 전체 갯수를 조회하기(모든 컬럼을 뜻하는 * 기호 사용해도 됨)
// COUNT() 함수 사용
String sql = "SELECT COUNT(board_num) FROM board"; // *로 가져와도 되지만 과부하가 걸림

pstmt = con.prepareStatement(sql);
rs = pstmt.executeQuery();

if(rs.next()) {
listCount = rs.getInt(1);
}
} catch (SQLException e) {
// e.printStackTrace();
System.out.println("BoardDAO - selectListCount() 실패! : " + e.getMessage());

} finally {
close(rs);
close(pstmt);
}

return listCount;
}
  • 메서드 완성시키기

< BoardListAction.java >

  • 한 줄 추가!

  • 새로고침 해보면
  • 전체 게시물 수 조회됨

 

< BoardListService.java >

public ArrayList<BoardBean> getArticleList(int page, int limit) {
System.out.println("BoardListService - getArticleList()");

ArrayList<BoardBean> articleList = null;

// DB 작업을 위한 준비 => Connection 객체, DAO 객체, DAO 객체의 메서드 호출
// 1. DB 작업에 필요한 Connection 객체 가져오기
Connection con = getConnection();

// 2. DB 작업을 위한 BoardDAO 객체 생성 => 싱글톤 패턴으로 생성된 객체 가져오기
BoardDAO boardDAO = BoardDAO.getInstance();

// 3. BoardDAO 객체에 Connection 객체 전달
boardDAO.setConnection(con);

// 4. BoardDAO 클래스의 selectArticleList() 메서드를 호출하여
//    => 페이지번호(page)와 글 갯수(limit)를 사용하여
//       지정된 번호부터 지정된 게시물 갯수만큼 게시물 가져오기
//    파라미터 : page, limit
//    리턴타입 : ArrayList<BoardBean>
articleList = boardDAO.selectArticleList(page, limit);


// 5. Connection 객체 반환
close(con);

return articleList;
}
  • 메서드 자동완성

< BoardDAO.java >

public ArrayList<BoardBean> selectArticleList(int page, int limit) {
System.out.println("BoardListService - selectArticleList()");
ArrayList<BoardBean> articleList = null;

return articleList;
}
  • 껍데기만 만들어두고 확인해보기

 

609p

< BoardDAO.java >

// 지정된 갯수 만큼의 게시물 목록 가져오기
// => 파라미터로 현재 페이지번호(page) 와 가져올 게시물 수(limit) 전달받음
public ArrayList<BoardBean> selectArticleList(int page, int limit) {
PreparedStatement pstmt = null;
ResultSet rs = null;

int startRow = (page - 1) * limit; // 가져올 게시물에 대한 시작 행 번호 계산

// 전제 게시물을 저장할 ArrayList 객체를 생성 => 제네릭 타입 BoardBean 타입 지정
ArrayList<BoardBean> articleList = new ArrayList<BoardBean>();

try {
// 게시물 갯수 조회할 SQL 구문 작성
// => 정렬 : board_re_ref 기준 내림차순, board_re_seq 기준 오름차순
// => limit : 시작 행 번호부터 지정된 게시물 갯수만큼 제한
String sql = "SELECT * FROM board ORDER BY "
+ "board_re_ref DESC, board_re_seq ASC LIMIT ?,?";
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, startRow);
pstmt.setInt(2, limit);
rs = pstmt.executeQuery();

// 조회된 레코드 만큼 반복
while(rs.next()) {
// 1개 레코드(게시물)를 저장할 BoardBean 객체 생성
BoardBean article = new BoardBean();
// BoardBean 객체에 조회된 레코드(게시물) 정보를 저장
article.setBoard_num(rs.getInt("board_num"));
article.setBoard_name(rs.getString("board_name"));
article.setBoard_pass(rs.getString("board_pass"));
article.setBoard_subject(rs.getString("board_subject"));
article.setBoard_content(rs.getString("board_content"));
article.setBoard_file(rs.getString("board_file"));
article.setBoard_re_ref(rs.getInt("board_re_ref"));
article.setBoard_re_lev(rs.getInt("board_re_lev"));
article.setBoard_re_seq(rs.getInt("board_re_seq"));
article.setBoard_readcount(rs.getInt("board_readcount"));
article.setBoard_date(rs.getDate("board_date"));

// 전체 레코드 저장하는 ArrayList 객체에 1개 레코드를 저장한 BoardBean 객체 전달
articleList.add(article);
}
} catch (SQLException e) {
// e.printStackTrace();
System.out.println("BoardDAO - selectArticleList() 실패! : " + e.getMessage());
} finally {
close(rs);
close(pstmt);
}

return articleList;
}

 

< BoardListAction.java >

ArrayList<BoardBean> articleList = boardListService.getArticleList(page, limit);
for(BoardBean article : articleList) {
System.out.println("제목 : " + article.getBoard_subject());
}
  • 확장 for문을 통해 객체가 잘 들고와지는지 확인해보기

 

======== vo 패키지에 PageInfo.java 만들기

package vo;

// 페이징 처리 정보를 저장하는 PageInfo 클래스 정의
public class PageInfo {
private int page;
private int maxPage;
private int startPage;
private int endPage;
private int listCount;

// 기본 생성자 정의
public PageInfo() {}

// 파라미터 5개 전달받는 생성자 정의
public PageInfo(int page, int maxPage, int startPage, int endPage, int listCount) {
super();
this.page = page;
this.maxPage = maxPage;
this.startPage = startPage;
this.endPage = endPage;
this.listCount = listCount;
}

// Getter / Setter 정의
public int getPage() {
return page;
}

public void setPage(int page) {
this.page = page;
}

public int getMaxPage() {
return maxPage;
}

public void setMaxPage(int maxPage) {
this.maxPage = maxPage;
}

public int getStartPage() {
return startPage;
}

public void setStartPage(int startPage) {
this.startPage = startPage;
}

public int getEndPage() {
return endPage;
}

public void setEndPage(int endPage) {
this.endPage = endPage;
}

public int getListCount() {
return listCount;
}

public void setListCount(int listCount) {
this.listCount = listCount;
}

}

 

< BoardListAction.java >

// 페이징 처리를 위해 페이지 수 계산
// 1. 최대 페이지 번호 계산 : 전체 게시물 수 / limit 결과를 반올림 처리하기 위해 0.95를 더함
// Math 클래스의 round() 호출해도 되지만 이게 코드가 짧음!
int maxPage = (int)((double)listCount / limit + 0.95);
// 2. 현재 페이지에서 표시할 시작 페이지 번호 계산(1, 11, 21...)
int startPage = (((int)((double)page / 10 + 0.9)) - 1) * 10 + 1;
// 3. 현재 페이지에서 표시할 끝 페이지 번호 계산(10, 20, 30...)
int endPage = startPage + 10 - 1;
// 단, 끝 페이지 번호가 최대 페이지 번호보다 클 경우
// => 최대 페이지 번호를 끝 페이지 번호로 사용
if(endPage > maxPage) {
endPage = maxPage;
}

// 페이징 정보를 저장할 PageInfo 객체 생성 및 데이터 저장
PageInfo pageInfo = new PageInfo(page, maxPage, startPage, endPage, listCount);

// request 객체에 PageInfo 객체와 ArrayList 객체 저장
request.setAttribute("pageInfo", pageInfo);
request.setAttribute("articleList", articleList);

 

728x90

'Dev.Program > Java & Spring' 카테고리의 다른 글

MVC2 - (5)  (0) 2022.10.07
MVC2 - (4)  (0) 2022.10.07
MVC2 - (2) Service 클래스  (0) 2022.10.07
MVC2 - (1)  (0) 2022.10.07
자바 Swing(스윙) - (5)  (0) 2022.10.06