Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
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
Tags
more
Archives
Today
Total
관리 메뉴

개발자 도전기

[Spring] 게시판 페이징 처리 본문

개발공부/Spring

[Spring] 게시판 페이징 처리

jnnjnn 2024. 4. 19. 21:33

게시판 구현

  • LIMIT(?,10)을 사용하여 DB의 Employees를 한 페이지당 10명씩 보여준다
  • 페이지는 10개 단위로 출력한다
  • 맨 처음에는 1 페이지가 출력된다
  • 다음 버튼을 누르면 (해당 라인 첫번째 페이지 + 10)인 페이지로 이동한다 ( 3 -> (다음) -> 11페이지)
  • 이전 버튼을 누르면 (해당 라인 첫번째 페이지 - 10)인 페이지로 이동한다 ( 27 -> (이전) -> 21페이지)
  • 제일 처음 줄에서는 이전 버튼이 보이지 않는다
  • 마지막 줄에서는 다음 버튼이 보이지 않는다
  • 맨앞 버튼을 누르면 1페이지로 이동한다
  • 1페이지에서는 맨앞 버튼이 보이지 않는다
  • 맨뒤 버튼을 누르면 가장 마지막 페이지로 이동한다
  • 가장 마지막 페이지에서는 맨뒤 버튼이 보이지 않는다

 

@Autowired
    private DataSource dataSource;

@GetMapping("sub2")
public String method2(@RequestParam(defaultValue = "1") Integer page, Model model) throws Exception {
    // 커넥션 객체 생성
    Connection conn = dataSource.getConnection();
    
    // 총 Employees 수 구하는 쿼리문
    String countSql = """
            SELECT COUNT(*)
            FROM Employees
            """;
    
    // 스테이트먼트 만들고 ResultSet에 쿼리문 대입
    Statement stmt = conn.createStatement();
    ResultSet countRs = stmt.executeQuery(countSql);
    
    // 총 Employees수 total에 담기
    countRs.next();
    int total = countRs.getInt(1);
    
    // 마지막 페이지 구하기
    int lastPage = (total - 1) / 10 + 1;
    
    
	// EmployeeID 순서대로 10개씩 출력하는 쿼리문
    String sql = """
            SELECT *
            FROM Employees
            ORDER BY EmployeeID
            LIMIT ?, 10
            """;
    
    // 페이지 기준으로 offset 정하기
    // 1페이지는 0 부터 10개 출력
    // 2페이지는 10부터 10개 출력
    int offset = (page - 1) * 10;
    
    var list = new ArrayList<MyBean255Employee>();
    
    // preparedstatement 생성하고 ? 에 offset 대입
    PreparedStatement pstmt = conn.prepareStatement(sql);
    pstmt.setInt(1, offset);
    
    // Result 생성하고 모든 데이터 list에 담기
    ResultSet rs = pstmt.executeQuery();
    try (stmt; conn; rs; countRs; pstmt) {
        while (rs.next()) {
            MyBean255Employee row = new MyBean255Employee();
            row.setEmployeeID(rs.getString(1));
            row.setLastName(rs.getString(2));
            row.setFirstName(rs.getString(3));
            row.setBirthDate(rs.getString(4));
            row.setPhoto(rs.getString(5));
            row.setNotes(rs.getString(6));

            list.add(row);
        }
    }
    // model에 list 담기
    model.addAttribute("employees", list);

	// 10개 단위로 출력할 페이지의 처음 페이지와 마지막 페이지 구하기
    // 맨 끝에는 마지막 페이지 출력
    int endPageNumber = (((page - 1) / 10) + 1) * 10;
    endPageNumber = Math.min(lastPage, endPageNumber);
    int beginPageNumber = endPageNumber - 9;

	// 현재 페이지, 가장 마지막 페이지, begin, end 페이지 모델에 담기
    model.addAttribute("currentPage", page);
    model.addAttribute("lastPage", lastPage);
    model.addAttribute("beginPageNumber", beginPageNumber);
    model.addAttribute("endPageNumber", endPageNumber);

	// 다음 10개 값이 있을때만 nextPageNumber 모델에 담기
    int nextPageNumber = beginPageNumber + 10;
    if (nextPageNumber <= lastPage) {
        model.addAttribute("nextPageNumber", nextPageNumber);
    }
    // 이전 10개 값이 있을때만 prevPageNumber 모델에 담기
    int prevPageNumber = beginPageNumber - 10;
    if (prevPageNumber >= 1) {
        model.addAttribute("prevPageNumber", prevPageNumber);
    }
    
    return "main25/sub8EmployeeList";
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h4>직원 목록 검색</h4>
<style>
    tr,
    table,
    td,
    th {
        border: 1px solid black;
        padding: 2px;
        justify-content: center;
    }
    .action {
        background-color: lightblue;
        color: white;
    }
    
</style>
<div>
    <c:if test="${currentPage != 1}">
        <c:url value="/main27/sub2" var="link">
            <c:param name="page" value="1"/>
        </c:url>
        <span>
            <a href="${link}">맨앞</a>
        </span>
    </c:if>
    <c:if test="${not empty prevPageNumber}">
        <c:url value="/main27/sub2" var="link">
            <c:param name="page" value="${prevPageNumber}"/>
        </c:url>
        <span>
            <a href="${link}">이전</a>
        </span>
    </c:if>
    <c:forEach begin="${beginPageNumber}" end="${endPageNumber}" var="page">
        <c:url value="/main27/sub2" var="link">
            <c:param name="page" value="${page}"/>
        </c:url>
        <span>
        <%-- 현재 선택한 페이지 스타일 주기 --%>
        <a class="${currentPage eq page ? 'action' : ''}" href="${link}">${page}</a>
        </span>
    </c:forEach>
    <c:if test="${not empty nextPageNumber}">
        <c:url value="/main27/sub2" var="link">
            <c:param name="page" value="${nextPageNumber}"/>
        </c:url>
        <span>
            <a href="${link}">다음</a>
        </span>
    </c:if>
    <c:if test="${currentPage != lastPage}">
        <c:url value="/main27/sub2" var="link">
            <c:param name="page" value="${lastPage}"/>
        </c:url>
        <span>
            <a href="${link}">맨뒤</a>
        </span>
    </c:if>
</div>
<table>
    <thead>
    <tr>
        <th>ID</th>
        <th>LastName</th>
        <th>FirstName</th>
        <th>BirthDate</th>
        <th>Photo</th>
        <th>Notes</th>
    </tr>
    </thead>
    <tbody>
    <c:forEach items="${employees}" var="employee">
        <tr>
            <td>${employee.employeeID}</td>
            <td>${employee.lastName}</td>
            <td>${employee.firstName}</td>
            <td>${employee.birthDate}</td>
            <td>${employee.photo}</td>
            <td>${employee.notes}</td>
        </tr>
    </c:forEach>
    </tbody>
</table>
</body>
</html>
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MyBean255Employee {
    private String employeeID;
    private String lastName;
    private String firstName;
    private String birthDate;
    private String photo;
    private String notes;
}