728x90
Spring, Hibernate JPA, Thymeleaf, Bootstrap을 이용한 Pagination하는 방법을 정리해 보자
개발자는 설명보다는 소스를 보기 편하니까 여기에서는 조건과 정의한 내용에 대해서만 간략하게 정리하고 넘어간다.
소스는 gist에 올려뒀다.
1. 조건
- 사용자 리스트를 보여주고, Row는 10줄로 한정한다.
- 현재 데이터는 10건이상이 있다고 가정한다.
2. Model 정의
- 사용자 모델은 이름, 설명, 연락처, 이메일 주소를 갖고 있다.
- https://gist.github.com/Prographer/a62fbf5bcedc2bfc6db3#file-user-java
3. Repository 정의
- PagingAndSortingRepository를 상속 받은 Interface를 정의 한다.
- https://gist.github.com/Prographer/a62fbf5bcedc2bfc6db3#file-userrepository-java
4. Controller 정의
- PageRequest를 이용하여 Page를 리턴 받는 Controller를 정의 한다.
- 재사용을 위해 리턴 결과는 pages 에 담아서 전달한다.
- https://gist.github.com/Prographer/a62fbf5bcedc2bfc6db3#file-usercontroller-java
5. view 정의
- Fragment로 정의 하여 재사용 가능 하게 작성 한다.
- https://gist.github.com/Prographer/a62fbf5bcedc2bfc6db3#file-pagination-html
6. 소스 보기
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="ko" | |
xmlns:th="http://www.thymeleaf.org"> | |
<head> | |
<meta charset="utf-8"/> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"/> | |
<meta name="viewport" content="width=device-width, initial-scale=1"/> | |
<!-- Latest compiled and minified CSS --> | |
<link rel="stylesheet" href="../../static/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}"> | |
<!-- Optional theme --> | |
<link rel="stylesheet" href="../../static/css/bootstrap-theme.css" th:href="@{/css/bootstrap-theme.css}"> | |
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> | |
<!--[if lt IE 9]> | |
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> | |
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> | |
<![endif]--> | |
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> | |
<script src="../../static/js/jquery-1.11.3.min.js" th:src="@{/js/jquery-1.11.3.min.js}"></script> | |
<!-- Include all compiled plugins (below), or include individual files as needed --> | |
<script src="../../static/js/bootstrap.min.js" th:src="@{/js/bootstrap.min.js}"></script> | |
</head> | |
<body> | |
<ul th:fragment="pagination" class="pagination"> | |
<li th:class="${pages.number eq 0}?'disabled':''"> | |
<a th:if="${pages.number eq 0}" href="javascript:void(0)" aria-label='Previous'><span aria-hidden='true'>«</span></a> | |
<a th:unless="${pages.number eq 0}" th:href="@{__${#httpServletRequest.requestURI}__(page=${pages.number-1})}" aria-label='Previous'><span aria-hidden='true'>«</span></a> | |
</li> | |
<li th:each="no:${#numbers.sequence(0, pages.totalPages-1)}" th:class="${pages.number eq no}?'active':''"> | |
<a th:href="@{__${#httpServletRequest.requestURI}__(page=${no})}" th:inline="text">[[${no+1}]]</a> | |
</li> | |
<li th:class="${pages.number+1 ge pages.totalPages}?'disabled':''"> | |
<a th:if="${pages.number+1 ge pages.totalPages}" href="javascript:void(0)" aria-label='Next'><span aria-hidden='true'>»</span></a> | |
<a th:unless="${pages.number+1 ge pages.totalPages}" th:href="@{__${#httpServletRequest.requestURI}__(page=${pages.number+1})}" aria-label='Next'><span aria-hidden='true'>»</span></a> | |
</li> | |
</ul> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.prographer.pagination.model; | |
import com.fasterxml.jackson.annotation.JsonIgnore; | |
import org.hibernate.annotations.Type; | |
import org.springframework.data.jpa.domain.AbstractPersistable; | |
import javax.persistence.*; | |
import javax.validation.constraints.NotNull; | |
import java.util.Date; | |
import java.util.HashSet; | |
import java.util.Set; | |
@Entity | |
public class User extends AbstractPersistable<Long> { | |
@NotNull | |
private String name; | |
@Type(type = "text") | |
private String description; | |
private String contact; | |
private String email; | |
@Temporal(TemporalType.TIMESTAMP) | |
@JsonIgnore | |
private Date created; | |
@Temporal(TemporalType.TIMESTAMP) | |
@JsonIgnore | |
private Date updated; | |
@PrePersist | |
protected void onCreate() { | |
created = new Date(); | |
updated = new Date(); | |
} | |
@PreUpdate | |
protected void onUpdate() { | |
updated = new Date(); | |
} | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
public String getDescription() { | |
return description; | |
} | |
public void setDescription(String description) { | |
this.description = description; | |
} | |
public String getContact() { | |
return contact; | |
} | |
public void setContact(String contact) { | |
this.contact = contact; | |
} | |
public String getEmail() { | |
return email; | |
} | |
public void setEmail(String email) { | |
this.email = email; | |
} | |
public Date getCreated() { | |
return created; | |
} | |
public Date getUpdated() { | |
return updated; | |
} | |
public void copy(Advertiser advertiser) { | |
this.name = advertiser.getName(); | |
this.contact = advertiser.getContact(); | |
this.email = advertiser.getEmail(); | |
this.description = advertiser.getDescription(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.prographer.pagination.controller; | |
import com.prographer.pagination.model.User; | |
import com.prographer.pagination.repository.UserRepository; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.data.domain.Page; | |
import org.springframework.data.domain.PageRequest; | |
import org.springframework.security.core.context.SecurityContextHolder; | |
import org.springframework.stereotype.Controller; | |
import org.springframework.web.bind.annotation.*; | |
import org.springframework.web.servlet.ModelAndView; | |
@Controller | |
public class AdvertiserController { | |
@Autowired | |
AdvertiserRepository advertiserRepository; | |
@RequestMapping | |
private ModelAndView index(@RequestParam(defaultValue = "0", required = false) int page) { | |
ModelAndView mav = new ModelAndView("/list"); | |
PageRequest pageRequest = new PageRequest(page,10); | |
mav.addObject("pages", advertiserRepository.findAll(pageRequest)); | |
return mav; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.prographer.pagination.repository; | |
import com.prographer.pagination.model.User; | |
import org.springframework.data.repository.PagingAndSortingRepository; | |
public interface UserRepository extends PagingAndSortingRepository<User, Long> { | |
User findByEmail(String email); | |
} |
끗
728x90
댓글