iBatis - Pagination 페이지 + 검색기능
PageVO
/**
* 페이징 처리와 관련된 모든 데이터를 가진 객체 . setTotalRecord/setCurrentPage 가 호출되어야 연산 완료.
*
* @param <T>
*/
@Getter
@NoArgsConstructor // 기본생성자
public class PagingVO<T> {
public PagingVO(int screenSize, int blockSize) {
super();
this.screenSize = screenSize;
this.blockSize = blockSize;
}// 임의변경
private int totalRecord; // DB 조회
private int totalPage;// 토탈레코드가 결정되면 토탈페이지도 결정
private int screenSize ; // 임의 결정
private int blockSize ; // 임의 결정
private int currentPage;// 사용자의 파라미터
private int startRow;
private int endRow;
private int startPage;
private int endPage;
private List<T> dataList; // 페이징vo가 모든 데이터 갖게됨
totalRecord : DB select했을때 갯수
totalPage : 몇개의 페이지를 만들건지
screenSize : 한페이지에 몇개의 게시글조회목록이 뜨는지
blockSize : 이전/ 1 2 3 / 다음, 여기 블럭사이즈
currentPage 현재페이지 -> 현재페이지가 null이면 1부터시작하는거고 현재페이지=start페이지이면 사용자가 입력한 페이지가 뜨는거다 ( 2페이지 누르면 2페이지로 뜨는거)
/**
* 단순키워드 검색용
*/
private SimpleSearchCondition simpleCondition;
public void setTotalRecord(int totalRecord) {
this.totalRecord = totalRecord;
this.totalPage = (totalRecord + (screenSize - 1)) / screenSize;// 서비스에서
}
public void setCurrentPage(int currentPage) {// 컨트롤러에서호출
this.currentPage = currentPage;
this.endRow = screenSize * currentPage;
this.startRow = endRow - (screenSize - 1);
this.endPage = ((currentPage + (blockSize - 1)) / blockSize) * blockSize;
this.startPage = endPage - (blockSize - 1);
}
public void setDataList(List<T> dataList) {
this.dataList = dataList;
}
public void setSimpleCondition(SimpleSearchCondition simpleCondition) {
this.simpleCondition = simpleCondition;
}
setTotalRecord(int totalRecord)
- 전체 조회 갯수가 몇개인지에 대한 setter
-여기안에서 totalpage도 생성해준다.
setCurrentPage
-currentPage 알면 startrow, endrow 계산할수있다. -> endPage, startPage도 알수있다.
setDataList(List<T> dataList>
-내가 가져다 쓸 List를 제너릭T 에 반환하는 setter 예) List<MemberVO> dataList
setSimpleCondition
-검색기능에서 가져다 쓸 상태 setter + 추후 설명 등록
private static final String PAGINGTRN = "<a href='#' data-page='%d'>%s</a>";
public String getPagingHTML() {
endPage = endPage > totalPage ? totalPage : endPage;
StringBuffer html = new StringBuffer();
if (startPage > blockSize) {
html.append(String.format(PAGINGTRN, (startPage - blockSize), "이전"));
}
for (int page = startPage; page <= endPage; page++) {
html.append(String.format(PAGINGTRN, page, Integer.toString(page)));
}
if(totalPage > endPage) {
html.append(String.format(PAGINGTRN, (endPage + 1), "다음"));
}
return html.toString();
}
private static final String BSPTRN = "<li class='page-item %s' %s><a class='page-link' href='#' data-page='%d'>%s</a></li>";
private String makePreviousLink() {
boolean disabled = startPage <= blockSize;
return String.format(BSPTRN,
disabled?"disabled":"",
"",
startPage-blockSize,
"이전");
}
private String makePageLink() {
StringBuffer pageLink = new StringBuffer();
endPage = endPage > totalPage ? totalPage : endPage;
for(int page=startPage; page<=endPage; page++) {
boolean active = page == currentPage;
pageLink.append(
String.format(BSPTRN,
active?"active":"",
"aria-current='page'",
page,
Integer.toString(page))
);
}
return pageLink.toString();
}
private String makeNextLink() {
boolean disabled = totalPage <= endPage;
return String.format(BSPTRN,
disabled?"disabled":"",
"",
endPage + 1,
"다음");
}
public String getPagingHTMLBS() {
StringBuffer html = new StringBuffer();
html.append(" <nav aria-label='...'> ");
html.append(" <ul class='pagination'> ");
html.append(makePreviousLink());
html.append(makePageLink());
html.append(makeNextLink());
html.append(" </ul> ");
html.append(" </nav> ");
return html.toString();
}
}
VO에서 페이징UI를 StringBuffer로 그려준다! jsp에서 el연산자로 ${paginHTMLBS}라고 쓰면 해당 값이 보여짐 !!
MemberDAO
public int selectTotalRecord(PagingVO<MemberVO> pagingVO);
/**
* 회원목록조회 return 존재하지 않는 경우, size() ==0
* @param pagingVO TODO
*/
public List<MemberVO> selectMemberList(PagingVO<MemberVO> pagingVO);
기존 DAO에 토탈레코드가 몇개인지 조회한 "selectTotalRecord"를 만든다 이때 return값은 PagingVO<MemberVO> - PagingVO에서 만들어준 property private List<T> dataList; // 페이징vo가 모든 데이터 갖게됨
그러면 selectMemberList<MemberVO> return값도 PagingVO로 반환되어야한다.
MemberDaoImpl
@Override
public List<MemberVO> selectMemberList(PagingVO<MemberVO> pagingVO) {
try (
SqlSession sqlSession = sqlSessionFactory.openSession();
){
// return sqlSession.selectList("kr.or.ddit.member.dao.MemberDAO.selectMemberList");
MemberDAO mapperProxy = sqlSession.getMapper(MemberDAO.class);
return mapperProxy.selectMemberList(pagingVO);
}
}
@Override
public int selectTotalRecord(PagingVO<MemberVO> pagingVO) {
try(
SqlSession sqlSession = sqlSessionFactory.openSession();
){
MemberDAO mapper = sqlSession.getMapper(MemberDAO.class);
return mapper.selectTotalRecord(pagingVO);
}
}
selectTotalRecord 추가해주고 selectMemberList는 리턴값을 바꿔줌
MemberService
public List<MemberVO> retrieveMemberList(PagingVO<MemberVO> pagingVO);
Dao랑 리턴값이 맞도록 바꿔준다.
MemberServiceImpl
@Override
public List<MemberVO> retrieveMemberList(PagingVO<MemberVO> pagingVO) {
pagingVO.setTotalRecord(memberDao.selectTotalRecord(pagingVO));
List<MemberVO> memberList = memberDao.selectMemberList(pagingVO);
pagingVO.setDataList(memberList);
return memberList;
}
마찬가지로 PagingVO<MemberVO>로 바꿔주고
Page를 할려면 전체레코드가 몇개인지알아야하므로 pagingVo에 있는 setTotalRecord를 해주면 setTotalRecord안에서 현재페이지 시작페이지 끝페이지 페이지사이즈 등을 다 설정해줄수있기때문에 setter를 받는데 그전에 memberDao안에있는 selectTotalRecord를 통해 totalRecord를 가져온다.
MemberListServlet
/**
* 회원 목록을 조회하기 위한 Controller Layer
*
*/
@WebServlet("/member/memberList.do")
public class MemberListServlet extends HttpServlet {
MemberService service = new MemberServiceImpl();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
String searchType = req.getParameter("searchType");
String searchWord = req.getParameter("searchWord");
String pageParam = req.getParameter("page");
SimpleSearchCondition searchVO = new SimpleSearchCondition(searchType, searchWord);
//검색조건을 하나의 객체로 묶어놓음 ,pagingVO안에 넣어야함
int currentPage= 1;
if(StringUtils.isNumeric(pageParam)) {
currentPage=Integer.parseInt(pageParam);
}
PagingVO<MemberVO> pagingVO = new PagingVO<>(5,3);
pagingVO.setCurrentPage(currentPage);
pagingVO.setSimpleCondition(searchVO);
service.retrieveMemberList(pagingVO);
req.setAttribute("pagingVO", pagingVO);
DelegatingViewResolver resolver = new DelegatingViewResolver();//실제로 해ㅕㄱㄹ x 또다른 resolver로 넘겨버림
String viewName = "/member/memberList.tiles";//member/memberList가 로직컬 뷰 네임
resolver.viewResolve(viewName, req, resp);
}
}
1. setCharacterEncoding으로 인코딩부터해줌
2. getParameter로 searchType, SerchWord //검색기능, page ( jsp에 있는 let page = $(this).data("page"); 값을 가져온다. )
3.pageParam이 숫자이면 if문안에 넣고 아니면 currentPage=1로 인식되어 첫페이지가 1이다.
4.paging의 생성자를 불러서 screenSize와 blockSize를 임의로 설정해준다.