簡単SpringBoot,Thymeleafでページネーションを実装

# やりたいこと
下記のようにページネーション機能を実装する。
![ページネーション1 2023-09-26 .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3185982/e5460dbf-2184-9b6a-bb6c-4e81c407c97b.png)
![ページネーション2 103854.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3185982/9efe3c45-6cc3-42b2-c8ed-6ad6501b9628.png)

# 環境
springboot2.7.7
java 11
postgres

# 実装手順
①Entity
②Repository
③Service
④Controller
⑤Html

# ①Entity
```java
@Entity
@Table(name = "goods")
@Getter
@Setter
public class Goods {
    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column
    private String name;

    @Column
    private Integer price;

    @Column(name = "category_name")
    private String categoryName;

    @Column
    private String note;

```

# ②Repository
クエリメソッドの引数Pageable型の引数を追加する。
```java
@Repository
public interface GoodsRepository extends JpaRepository<Goods, Integer> {
    
    Page<Goods> findAllByOrderByIdAsc(Pageable pageable);
}
```

# ③Service
```java
@Service
public class GoodsService {

    @Autowired
    GoodsRepository goodsRepository;

public Page<Goods> findGoodsPage(Pageable pageable) {
        Page<Goods> results = goodsRepository.findAllByOrderByIdAsc(pageable);
        return results;
    }
}
```

# ④Controller
```java
@Controller
public class GoodsController {
    @Autowired
    GoodsService goodsService;
@GetMapping("/goods")
    public ModelAndView goods(@RequestParam(name="pages", required = false) String pages) {
        ModelAndView mav = new ModelAndView();
Pageable pageable = null;

        if(pages != null ) {
            pageable = parsePageable(pages);
        }
        if (pageable == null || pageable.getPageNumber() <= 0){
            pageable = PageRequest.of(0,5); //ここで１ページあたりの表示件数を設定している
        }

        Page<Goods> pagesList = goodsService.findGoodsPage(pageable);

        mav.addObject("pages", pagesList);
        //～～～～～～～～～～ページネーション終わり

        return mav;
    }

    private Pageable parsePageable(String str) {
        int page = parseInt(str); //文字列strを整数に変換する。
        return PageRequest.of(page,5);
    }
```

# ④Html

```html
<!--    ページネーション-->
    <div class="pagination" th:if="${pages.totalPages > 1}">
        <ul class="pagination">
            <!-- 最初のページへのリンク -->
            <li th:if="${not pages.first}">
                <a th:href="@{/customer(pages=0,name=${name},start=${start},end=${end})}">&lt;&lt; 最初へ</a>
            </li>

            <!-- 前のページへのリンク -->
            <li th:if="${pages.hasPrevious}">
                <a th:href="@{/customer(pages=${pages.number - 1},name=${name},start=${start},end=${end})}">&lt; 前へ</a>
            </li>

            <!-- 中間のページリンク -->
            <li th:each="i : ${#numbers.sequence(0, pages.totalPages - 1)}">
                <span th:if="${i == pages.number}"><span th:text="${i + 1}"></span></span>
                <a th:if="${i != pages.number}" th:href="@{/customer(pages=${i},name=${name},start=${start},end=${end})}">
                    <span th:text="${i + 1}"></span>
                </a>
            </li>

            <!-- 次のページへのリンク -->
            <li th:if="${pages.hasNext}">
                <a th:href="@{/customer(pages=${pages.number + 1},name=${name},start=${start},end=${end})}">次へ &gt;</a>
            </li>

            <!-- 最後のページへのリンク -->
            <li th:if="${not pages.last}">
                <a th:href="@{/customer(pages=${pages.totalPages - 1},name=${name},start=${start},end=${end})}">最後へ &gt;&gt;</a>
            </li>
        </ul>
    </div>
```

# まとめ
・引数にPageableを渡す、各ファイルでの値をPage型として返せば簡単に実装できます。


# 参考文献
spring徹底入門　著株式会社NTTデータ