# 六角鼠年鐵人賽 Week 30 - Spring Boot - Spring Data & JPA Paging 範例 ==大家好,我是 "為了拿到金角獎盃而努力著" 的文毅青年 - Kai== ## Marc Jacobs :::info You can never please everyone, and I think it's best not to. ::: ## 主題 這篇就來分享實作分頁功能的範例,同樣會利用到之前建構的資料與程式。 Kai 這邊新增一個 Controller,並在原先的 EmployeeRepository.java 中增加一個會用到的分頁方法。 透過 Pageable 物件設定頁、顯示筆數、排序依據,一次設定好所有分頁功能需要用到的參數,並將 Pageable 物件放入 Repository 的方法當中,Spring Data JPA 的套件會自動在 SQL 中生成相對應的分頁 SQL 語法後執行,並帶出最終結果,不需要開發者再去設定過多的處理。 ## JPAPagingController.java ```java= package kai.com.jpa.controller; import kai.com.jpa.entity.Employee; import kai.com.jpa.repository.EmployeeRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.web.bind.annotation.*; import java.sql.Date; import java.util.List; @RestController @RequestMapping("/getEmpPaging") public class JPAPagingTestController { @Autowired EmployeeRepository employeeRepository; @GetMapping("/build") public String buildTableAndData(){ /*** 建立測試資料 ***/ for(int i = 0; i < 20;i++) { Employee emp = new Employee(); emp.setEmp_name("Tester_"+i); emp.setEmp_team("IT"); emp.setEmp_birthDate(new Date(19920101)); employeeRepository.save(emp); } return "Done build."; } @GetMapping("/{page}/{rows}") public List<Employee> getAllByIDPaging(@PathVariable("page") int page, @PathVariable("rows") int rows){ Pageable pageable = PageRequest.of(page, rows, Sort.by("id")); return employeeRepository.findByIDPaging(pageable); } } ``` ## EmployeeRepository.java ```java= package kai.com.jpa.repository; import kai.com.jpa.entity.Employee; import kai.com.jpa.entity.Employee2; import kai.com.jpa.entity.QEmployee; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.Query; import org.springframework.data.querydsl.QuerydslPredicateExecutor; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; import java.util.List; import java.util.Optional; public interface EmployeeRepository extends CrudRepository<Employee, Long>{ @Query("FROM Employee as e") public List<Employee> findByIDPaging(Pageable pageable); } ``` ## Employee.java ```java= package kai.com.jpa.entity; import javax.persistence.*; import java.sql.Date; /* @NamedNativeQueries({ @NamedNativeQuery( name = "Employee.findByPriorityExclude", query = "SELECT * FROM Employee as e WHERE e.emp_id <> ?1", resultClass=Employee.class ) }) */ @Entity public class Employee { public Employee (){} public Employee(String name, String team, Date birthDate){ this.emp_name = name; this.emp_team = team; this.emp_birthDate = birthDate; } @Id @GeneratedValue(strategy= GenerationType.AUTO) private Long emp_id; private String emp_name; private String emp_team; private Date emp_birthDate; public Long getEmp_id() { return emp_id; } public void setEmp_id(Long emp_id) { this.emp_id = emp_id; } public String getEmp_name() { return emp_name; } public void setEmp_name(String emp_name) { this.emp_name = emp_name; } public String getEmp_team() { return emp_team; } public void setEmp_team(String emp_team) { this.emp_team = emp_team; } public Date getEmp_birthDate() { return emp_birthDate; } public void setEmp_birthDate(Date emp_birthdate) { this.emp_birthDate = emp_birthdate; } } ``` ## 成果 > 建置好資料 ![](https://i.imgur.com/kuEyv42.png) > 以五個一頁,第 1 頁 (頁數以 0 為起始) ![](https://i.imgur.com/XBlkW7y.png) > 以五個一頁,第 4 頁 > ![](https://i.imgur.com/R6TtTXo.png) > 以五個一頁,第 5 頁 (不存在的頁數) ![](https://i.imgur.com/aDUl143.png) > 以八個一頁,第 3 頁 > ![](https://i.imgur.com/YV9gdho.png) ## 結語 從上述的範例中可以看到,當執行搜索不存在頁數的資料時候,並不會引起錯誤,僅會拋出空資料的集合回前端,以此避免許多後端苦惱的 **超出** 問題。 :::danger Spring Data & JPA 的部分在此告一個段落,有興趣的朋友可以自行往下深入學習,Kai 這邊如果已經沒有可以拓寬的題材時候,就會回頭來深入講些應用上比較常見的功能與做法。 若有什麼想了解的、想探討切磋的也可以提出來指教~ [六角鼠年鐵人賽 Week 31 - Spring Boot - Schedule Works](/EH8O4V6tQpGwfR_XRH31QA) ::: 首頁 [Kai 個人技術 Hackmd](/2G-RoB0QTrKzkftH2uLueA) ###### tags: `Spring Boot`,`Spring Data`,`w3HexSchool`