본문 바로가기

개인공부

페이징 처리

반응형

전체 DB의 수를 가져오는 함수

select count(*) from guestbook;

 

효율적인 처리를 위해서 limit 과 offset을 이용해서 필요한 페이지 만큼을 불러오겠다.

select * from guestbook
limit 2 offset 3;

 

위의 두가지 sql문법을 활용해서 효율적인 페이징 처리를 하려고한다.

 

 

기본적인 페이징 처리 원리

 

int totalCount = /*DB접속후 쿼리를 통해 얻은 값*/;
 
int listCount = 10;
 
int totalPage = (totalCount-1) / listCount + 1;
 
if (totalCount % listCount > 0) {
    totalPage++;
}

listCount 한페이지에 불러올 리스트의 양이다.

totalPage는 전체 페이지 수이다. 이때 +1 을 해주는이유는 나누어 떨어지는것을 방지하는 것이다.

//page = 현재 보고있는 페이지
if (totalPage < page){
    page = totalPage;
}

현재 페이지가 totalPage보다는 클수없으니 totalPage보다 커진다면 page = tatalPage로 유지 시켜준다.

int startPage = ((page - 1) / pageCount) * pageCount + 1;
//현재 페이지가 pageCount와 같을 때를 유의하며 (page-1)을 하고
// +1은 첫페이지가 0이나 10이 아니라 1이나 11로 하기 위함임
int endPage = startPage + pageCount - 1;
// -1은 첫페이지가 1이나 11 등과 같을때 1~10, 11~20으로 지정하기 위함임

pageCount는 페이지에 보일 양이다

if (endPage > totalPage) {
    endPage = totalPage;
}

endPage가 totalPage보다 클수는 없으니 endPage = totalPage로 초기화 해준다.

 

이젠 이거의 지식을 가지고 페이지를 불러와보자

 

본격적으로 PageVO 클래스클 구현해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class PageVO {
 
    private int totalData; // 총 데이터
    private int listCount = 10// 한 페이지에 보여줄 수
    private int pageCount = 10;
    private int startPage; // 시작페이지
    private int endPage; // 마지막 페이지
    private int totalPage; // 전체 페이지
    private int page;
 
    public void pageCalculate(int total, int p) {
        page = p;
        totalData = total;
        totalPage = (totalData -1/ listCount + 1;
 
        startPage = (page - (page - 1) % pageCount);
        endPage = startPage + (pageCount - 1);
 
        if (endPage > totalPage) endPage = totalPage;
        
    }
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter

 

위의 수식을 pageCalculate라는 함수를 통해서 모든값을 초기화해준다. 

이제 MainController에서 list를 어떻게 부를지 생각해보자.

 

Dao 안에서 현재불러올 DB의 전체 개수를 가져오는 함수를 구현해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    @Override
    public int totalCount() throws SQLException {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
 
        conn = DBUtil.getConnection();
        StringBuilder sql = new StringBuilder();
        sql.append("select count(*) as count \n");
        sql.append("from guestbook \n");
        pstmt = conn.prepareStatement(sql.toString());
 
        rs = pstmt.executeQuery();
        if (rs.next()) {
            return rs.getInt("count");
        }
        return 0;
    }
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter

 

이렇게 data안에 모든 함수를 count를 호출해서 전체 데이터의 수를 가져올 수 있다.

 

list 함수를 구현

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
    @Override
    public List<GuestBookDto> listArticle(String key, String word,int page) throws SQLException {
        List<GuestBookDto> list = new ArrayList<GuestBookDto>();
 
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
 
        try {
            conn = DBUtil.getConnection();
            StringBuilder sql = new StringBuilder();
            sql.append("select articleno, userid, subject, content, regtime \n");
            sql.append("from guestbook \n");
            if (!word.isEmpty()) {
                if ("subject".equals(key)) {
                    sql.append("where subject like ? \n");
                } else {
                    sql.append("where " + key + " = ? \n");
                }
            }
            sql.append("order by articleno desc \n");
            sql.append("limit 10 offset "+(page-1)*10 +1);
            
            pstmt = conn.prepareStatement(sql.toString());
            if (!word.isEmpty()) {
                if ("subject".equals(key))
                    pstmt.setString(1"%" + word + "%");
                else
                    pstmt.setString(1, word);
            }
            rs = pstmt.executeQuery();
            while (rs.next()) {
                GuestBookDto guestBookDto = new GuestBookDto();
                guestBookDto.setArticleno(rs.getInt("articleno"));
                guestBookDto.setUserid(rs.getString("userid"));
                guestBookDto.setSubject(rs.getString("subject"));
                guestBookDto.setContent(rs.getString("content"));
                guestBookDto.setRegtime(rs.getString("regtime"));
 
                list.add(guestBookDto);
            }
        } finally {
            DBUtil.close(rs);
            DBUtil.close(pstmt);
            DBUtil.close(conn);
        }
 
        return list;
    }
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter

이런식으로 모든 list를 불러올때 위에 limit과 offset을 이용해서 원하는 페이지를 불러올수가 있다.

 

main contror에서 list에 대한정보와 page에대한 정보를 setAttribute하고 forward로 전송한다.

			request.setAttribute("articles", list);
			request.setAttribute("pagevo", pageVO);

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    <ul class="pagination">
    <c:if test="${pagevo.startPage ne 1}">
        <li class="page-item"><a class="page-link" href="${root}/main.do?act=list&key=&word=&page=${pagevo.startPage -1}">Previous</a></li>
    </c:if>
 
    <c:forEach var="pageNum" begin="${pagevo.startPage}" end="${pagevo.endPage}">
        <c:choose>
            <c:when test="${pageNum eq pagevo.page}">
                <li class="page-item active"><a class="page-link" href="${root}/main.do?act=list&key=&word=&page=${pageNum}">${pageNum}</a></li>
            </c:when>
            <c:otherwise>
                <li class="page-item "><a class="page-link" href="${root}/main.do?act=list&key=&word=&page=${pageNum}"> ${pageNum} </a></li>
            </c:otherwise>
        </c:choose>
    </c:forEach>
 
    <c:if test="${pagevo.endPage ne pagevo.endPage}">
        <li class="page-item"><a class="page-link" href="${root}/main.do?act=list&key=&word=&page=${pagevo.endPage + 1}">Next</a></li>
    </c:if>
    </ul>
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

이처럼 page를 설정할수있다. a태그를 이용해서 page가 바뀌면 다시 maincontroler에서 계산하게된다.

key값과 word값은 설정하지 않았지만 향후 추가할수있다.

반응형

'개인공부' 카테고리의 다른 글

기초 : PC, 캐시, 버스 요약  (0) 2020.06.21
web 자주사용하는 태그들  (0) 2020.05.25
JSTL  (0) 2020.04.23
web공부  (0) 2020.04.21
GIT 시작하기(버전관리의 본질)  (0) 2020.03.13