ページネーションを実装  Pageableインターフェース / Pageインターフェース


# ページネーションを実装
`Pageable`インターフェイスを利用して実装
実装できる具体例

* ページ番号
* サイズ
* 並べ替え条件

### コントローラの設定変更 
`AdminHouseController.java`を以下のように変更
```Java:AdminHouseController.java変更箇所1
 -import java.util.List;

 +import org.springframework.data.domain.Page;
 +import org.springframework.data.domain.Pageable;
 ```
 ```Java:AdminHouseController.java変更箇所2
   @GetMapping
-     public String index(Model model) {
+	public String index(Model model, Pageable pageable) {
-         List<House> houses = houseRepository.findAll(); 
+         Page<House> housePage = houseRepository.findAll(pageable);
        
-        model.addAttribute("houses", houses);  
+         model.addAttribute("housePage", housePage);
```
ポイント
**1. メソッドにPageable型の引数を指定する**
メソッドにPageable型の引数を指定することで、Spring Boot側で適切なPageableオブジェクトを生成し、メソッド内で利用できるようにしてくれます。

**2. findAll()メソッドにPageableオブジェクトを渡す**
ページネーションされたデータを取得するためには、findAll()を始めとするリポジトリのメソッドの引数としてPageableオブジェクトを渡します。

なおfindAll()メソッドと同様、findAll(Pageable pageable)メソッドも自動的に実装されているため、リポジトリに自分で定義する必要はありません。

戻り値はPage型なので、Page型の変数に代入します。

![スクリーンショット 2024-02-23 20.39.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570384/86c76cd1-2dda-114e-1888-c0648bc39365.png)

```java
package com.example.samuraitravel.controller;

-import java.util.List;

+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort.Direction;
+import org.springframework.data.web.PageableDefault;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.example.samuraitravel.entity.House;
import com.example.samuraitravel.repository.HouseRepository;

@Controller
@RequestMapping("/admin/houses")
public class AdminHouseController {
    private final HouseRepository houseRepository;         
    
    public AdminHouseController(HouseRepository houseRepository) {
        this.houseRepository = houseRepository;                
    }	
    
    @GetMapping
-    public String index(Model model) {
+	public String index(Model model, Pageable pageable) {
-        List<House> houses = houseRepository.findAll(); 
+        Page<House> housePage = houseRepository.findAll(pageable);
        
-        model.addAttribute("houses", houses);  
+        model.addAttribute("housePage", housePage);
        
        return "admin/houses/index";
    }  
}

```
`@PageableDefault(size = 20)`で画面の表示件数を指定できる。
ブラウザで`http://localhost:8080/admin/houses?page=1&size=10&sort=id,DESC`と記述してブラウザから表示を変えることもできる。

 ### ビューの変更
 `index.html`を変更する。
`addAttribute()`メソッドの第1引数を変更したので、index.htmlも以下のように編集
 ```html
 <!--======== 前略 ========-->

            <main>
                <div class="container pt-4 pb-5 samuraitravel-container">
                    <div class="row justify-content-center">
                        <div class="col-xxl-9 col-xl-10 col-lg-11">
                            
                            <h1 class="mb-4 text-center">民宿一覧</h1>   
                            
                            <div class="d-flex justify-content-end">                                
                                <a href="#" class="btn text-white shadow-sm mb-3 samuraitravel-btn">登録</a>
                            </div>                                                          
                            
                            <table class="table">
                                <thead>
                                    <tr>
                                        <th scope="col">ID</th>
                                        <th scope="col">民宿名</th>
                                        <th scope="col">郵便番号</th>
                                        <th scope="col">住所</th>
                                        <th scope="col">電話番号</th>
                                        <th scope="col"></th>                                        
                                    </tr>
                                </thead>   
                                <tbody>                                                     
-                                    <tr th:each="house : ${houses}">
+                                    <tr th:each="house : ${housePage}">
                                        <td th:text="${house.getId()}"></td>
                                        <td th:text="${house.getName()}"></td>
                                        <td th:text="${house.getPostalCode()}"></td>
                                        <td th:text="${house.getAddress()}"></td>
                                        <td th:text="${house.getPhoneNumber()}"></td>
                                        <td><a href="#">詳細</a></td>                                                                                
                                    </tr>                                      
                                </tbody>
                            </table>                                       
                        </div>
                    </div>
                </div>              
            </main>
            
<!--======== 後略 ========-->
```
![スクリーンショット 2024-02-23 20.49.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570384/ed6c72e7-05ac-0c39-3b9f-b307e417da74.png)
### `@PageableDefault`アノテーションをつける
コントローラの中で下記のように`Pageable`オブジェクトが持つページ情報のデフォルト値を任意に設定できる。
```java
@GetMapping    
     public String index(Model model, Pageable pageable) {
 	public String index(Model model, @PageableDefault(page = 0, size = 10, sort = "id", direction = Direction.ASC) Pageable pageable) {	
        Page<House> housePage = houseRepository.findAll(pageable);
                
        model.addAttribute("housePage", housePage);
        
        return "admin/houses/index";
    }  
```


またはブラウザで`http://localhost:8080/admin/houses?page=1&size=10&sort=id,DESC`などのように設定した通りに表示されているはず。
設定できる項目は、
* ページ番号(デフォルトでは0)
* サイズ（1ページあたりの表示数、デフォルトではサイズが20）
* 並べ替えの条件(並べ替えの条件が指定されていない場合、一般的にはidが小さい順（昇順）で表示)
***