PageUtilBean을 Struts 2 게시판에서 사용하기
개요
PageUtilBean은 JSP 페이지 하단의 페이지 네비게이션 링크를 자동으로 생성해주는 기능을 한다
이렇게 기능하려면 우선 초기화가 필요한데, 인스턴스를 생성하고 init()을 호출하면 초기화할 수 있다.
JSP와 Bean 클래스로 구성된는 Model 1 방식, Servlet 이 사용되는 MVC 패턴 및 Struts 등에서도 사용할 수 있다.
PageUtilBean.init() 의 파라미터
init()메소드의 파라미터 타입과 그 의미는 다음과 같다
public void init(int currPage, List<BoardVO> list, int rowsPerPage, int numsPerPage)
int currPage |
이용자가 웹브라우저에서 요청한 현재 페이지 번호 |
List<BoardVO> list |
DAO 측에서 리턴된 리스트 (화면에 보여질 게시판 리스트) |
int rowsPerPage |
한 페이지에 보여줄 리스트의 행수 |
int numsPerPage |
한 페이지의 하단에 보여줄 페이지 링크의 수 |
BoardAction.java
public class BoardAction extends ActionSupport implements Preparable, ModelDriven<BoardVO> {
private BoardVO board;
private String resultMsg; //입력, 수정, 삭제시 결과 메시지 저장
private List<BoardVO> boardList;
private int num; //글번호
private int page = 1; //이용자가 요청한 페이지 번호
private PageUtilBean pageBean;
......
...........(중략)
/** 이용자가 리스트 요청시 실행되는 액션 메소드
PageUtilBean의 인스턴스를 생성하고 Service 객체로 전달한다
Service 객체의 getBoardList(page) 호출시 메소드 내부에서 PageUtilBean.init()호출하여 초기화 됨
PageUtilBean이 초기화되면 뒤 이어 호출되는 JSP에서 Action 의 멤버변수인 pageBean을 사용함
*/
public String boardList() throws Exception {
pageBean = new PageUtilBean();
BoardService service = new BoardService(pageBean);
boardList = service.getBoardList(page);
return SUCCESS;
}
/** 이용자가 요청한 특정 페이지 번호는 params 인터셉터에 의해 현재 액션의 멤버 변수인 page 에 설정된다 */
public void setPage(int page) {
this.page = page;
}
/** JSP 에서 ${pageBean.navStr}, ${pageBean.currPage}, ${pageBean.totalPages} 등을 사용할 수 있도록 getter 메소드 선언*/
public PageUtilBean getPageBean() {
return pageBean;
}
...........
........(생략)
}
BoardService.java
public class BoardService {
private PageUtilBean pageBean;
public BoardService(){}
public BoardService(PageUtilBean pageBean){
this.pageBean = pageBean;
}
public List<BoardVO> getBoardList(int page) {
BoardDao dao = new BoardDao();
int rowsPerPage = 3;
List<BoardVO> list = dao.boardList(page, rowsPerPage);
pageBean.init(page, list, rowsPerPage, 5);
return list;
}
........
..............(생략)
}
BoardDao.java
public ArrayList<BoardVO> boardList(int page, int rowsPerPage){
ArrayList<BoardVO> list = new ArrayList<BoardVO>();
conn = getConn();
String sql="select num, subject, writer, reg_date, page, ttpage, ttcnt from "+
"( "+
"select T1.*, rownum rn, "+
"CEIL(rownum/?) as PAGE, "+
"CEIL(TTCNT/?) as TTPAGE from "+
"( "+
"select b.*,COUNT(*)OVER() as TTCNT from board b order by num desc "+
") T1 "+
") "+
"where page=?";
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, rowsPerPage);
pstmt.setInt(2, rowsPerPage);
pstmt.setInt(3, page);
rs = pstmt.executeQuery();
while(rs.next()){
int number = rs.getInt("num");
String writer = rs.getString("writer");
String subject = rs.getString("subject");
Date reg_date = rs.getDate("reg_date");
/* 페이지 네비게이션 링크를 위해 PageUtilBean에서 필요한 정보 */
int pg = rs.getInt("page");
int ttpage = rs.getInt("ttpage");
int ttcnt = rs.getInt("ttcnt");
BoardVO vo = new BoardVO(number, writer, null, subject, null, reg_date, 0, null);
vo.setPageNo(pg);
vo.setTotalPages(ttpage);
vo.setTotalCnt(ttcnt);
list.add(vo);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(conn, pstmt, rs);
}
return list;
}
위에서 사용된 BoardVO 클래스는 Pageable 인터페이스를 구현해야 한다. Pageable 인터페이스에 선언된 메소드는 DAO측에서 setter 를 사용하고 PageUtilBean 측에서는 getter 를 사용한다
Pageable.java
package board;
/**
* 이 인터페이스는 데이터베이스 테이블의 한개의 레코드 정보를 저장할 클래스(VO)가
* 구현할 경우 PageUtilBean에서 연결하여 페이지 하단에 페이지 네비게이션 링크를 생성
* 하는 기능을 사용할 수 있다. DAO 측에서는 SQL을 사용하여 총 레코드 수(ttcnt),
* 총 페이지 수(ttpage), 현재 페이지 번호(page)를 VO에게 설정해야 주어야만
* PageUtilBean에서 VO에 접근하여 해당 정보를 기반으로 페이지 네비게이션 링크를 생성할 수 있다
* DAO측에서 사용하는 SQL문장의 형태는 이 코드 아래에 있는 예문을 참고하기 바란다
*/
public interface Pageable {
/**현재 페이지 번호*/
public int getPageNo();
public void setPageNo(int pageNo);
/**총 레코드 수*/
public int getTotalCnt();
public void setTotalCnt(int totalCnt);
/**총 페이지 수*/
public int getTotalPages();
public void setTotalPages(int totalPages);
}
/*
select rn, empno, ename, page, ttpage, ttcnt from
(
select T1.*, rownum rn,
FLOOR((rownum-1)/?+1) as page,
FLOOR((TTCNT-1)/?+1) as TTPAGE from
(
select e.*,COUNT(*)OVER() as TTCNT from emp e order by empno
) T1
)
where page=?
?:rowsPerPage
?:rowsPerPage
?:page
*/
BoardVO.java
public class BoardVO implements Pageable {
private int num;
private String writer;
private String email;
private String subject;
private String passwd;
private Date reg_date;
private int ref;
private String content;
/* Fields for Pageable */
private int pageNo;
private int totalCnt;
private int totalPages;
..............
............(중략)
@Override
public int getPageNo() {
return pageNo;
}
@Override
public void setPageNo(int pageNo) {
this.pageNo = pageNo;
}
@Override
public int getTotalCnt() {
return totalCnt;
}
@Override
public void setTotalCnt(int totalCnt) {
this.totalCnt = totalCnt;
}
@Override
public int getTotalPages() {
return totalPages;
}
@Override
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
}
JSP
<table >
<caption>${pageBean.currPage} / ${pageBean.totalPages} </caption>
<tr><th width="70">글번호</th><th width="300">제목</th><th width="100">작성자</th><th width="100">작성일</th></tr>
<s:iterator value="boardList">
<tr>
<td><s:property value="num"/></td>
<td align="left">
<s:url id="readUrl" action="boardRead">
<s:param name="num"><s:property value="num"/></s:param>
</s:url>
<s:a href="%{readUrl}"><s:property value="subject"/></s:a>
</td>
<td><s:property value="writer"/></td>
<td><s:date name="reg_date" format="yyyy-MM-dd"/></td>
</tr>
</s:iterator>
<tr><td id="navTd" colspan="4">${pageBean.navStr}</td></tr>
</table>
struts2_board_with_pagebean.zip