BETA

Springフレームワークを使ってページングを作成する方法(DBアクセスなし)

投稿日:2020-04-17
最終更新:2020-04-17

研修でSpringフレームワークを触っていた時に遭遇した問題なのですが、DBへのアクセスなしでページングってどうやんの?!?!って思ったので備忘録を兼ねて共有。
僕の知識が浅いだけで今は便利なライブラリとかたくさんあるのと、もしも見つからなかった時用にアルゴリズムも書いておくので参考にしてください。

今回はコントローラの書き方だけを書いておきます。
コードにSampleと書くので、Sampleの部分は適宜変えてください。

DBへのアクセスをした時のページング実装

DBへアクセスをするなら割と基本的な使い方なので皆さん知っていると思いますが、一応さらっとだけ紹介。

今回はさらっとだけなのでリポジトリに書く場合のみ紹介。

public Page<Sample> findAll(Pageable pageable);  

これでリポジトリ側のページングの処理は完了です。
なんて簡単なんだ。。

DBへのアクセスなしでのページングの実装方法

DBへのアクセスをするとページングをものすごく簡単に実装できるのですが、DBへのアクセスなしだとこれがまたしんどい。
ちなみに僕は全く見つからなくて苦労しました。

早く見せろよというせっかちな方に早速コード。

PagedListHolder<Sample> pagenation = new PagedListHolder<>(sampleList);  
// 現在のページ(0ページ目から開始する)  
pagenation.setPage(currentPage);  
// 1ページ当たりの表示件数  
pagenation.setPageSize(10);  

Springにもともと用意されているPagedListHolderクラスを利用するとセッションや取り込んだリスト等を使用したページングの作成が可能です。

ページングアルゴリズム公開

上のが見つからなかった時に自作したページングアルゴリズムです。
他言語でも書き方変えればできると思うので参考までに。

流れとしては、

  1. 取得したデータを1ページに表示したいデータの数だけ小さいリストに詰め替え
  2. 小さいリストを大きいリストに詰め込む
  3. 表示するときに大きいリストから該当ページの小さいリストを抜き取ってその中身を表示する

1と2を取得したデータの数だけ繰り返して3に移動みたいな形です。

package jp.co.sample.controller.sample;  

import java.util.ArrayList;  
import java.util.List;  

import javax.servlet.http.HttpSession;  

import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.data.repository.query.Param;  
import org.springframework.stereotype.Controller;  
import org.springframework.ui.Model;  
import org.springframework.web.bind.annotation.RequestMapping;  
import org.springframework.web.bind.annotation.RequestMethod;  
// エンティティもここでインポートして  

@Controller  
public class SampleAlgorithmController {  

    @Autowired  
    HttpSession session;  

    // sampleコントローラ  
    @RequestMapping(path = "/sample", method = RequestMethod.POST)  
    public String sample(@Param("page") String page, Model model) {  
        // ページングの作成アルゴリズム  
        if(session.getAttribute("sample") != null) {  
            // セッションから全てのデータを受け取る  
            List<Sample> sampleList = (List<Sample>)session.getAttribute("sample");  
            // ページング用の多次元リストを宣言  
            List<List<Sample>> pageList = new ArrayList<>();  
            // 1ページ分のデータを格納するリストを宣言  
            List<Sample> pages = new ArrayList<>();  

            // ページ番号を取得  
            // ここで宣言しとかないと後で変数ないよと怒られる  
            int pageNum = 0;  
            // page変数に値があって整数の場合、ページ番号をint型に変換  
            if(page != null && page.matches("^\\d+$")) {  
                pageNum = Integer.parseInt(page);  
            }  

            // ループ回数  
            int count = 1;  

            // 今回は10件のデータを1ページに詰める  
            // 表示させる件数によってデータは変えて下さい  
            int dataForOnePage = 10;  

            // セッションの中身をループで詰めなおし  
            for(Sample s : sampleList) {  
                // 1ページ分の情報をリストに詰める  
                pages.add(s);  
                if(count % dataForOnePage == 0) {  
                    pageList.add(pages);  
                    // pages変数に新しいインスタンスを代入して空にする(そうしないと参照型なのでぐちゃぐちゃになる)  
                    pages = new ArrayList<>();  
                }  

                count++;  
            }  

            // 10の倍数件でなければaddされてないページがあるのでそれを追加  
            if(pages.size() != 0) {  
                pageList.add(pages);  
            }  

            // セッションに求められたページだけをセット  
            session.setAttribute("samplePage", pageList.get(pageNum));  
            // 総ページ数と現在のページ番号をリクエストスコープにセット  
            // ここはview側の処理によるので書き換えてOK  
            model.addAttribute("total", pageList.size());  
            model.addAttribute("current", pageNum);  
        }  

        return "sample/pageSample";  
    }  
}  
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@umesanの技術ブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう