なんだかGoodVibes

日々の勉強メモです。

【Node】MYSQL操作の基本(ページネーション)

本日はページネーションの利用。
各ページへのリンクを作成してみます。


概要

データを表示するページの下部に
最初・最後・次のページ・前のページへの
リンクを作成します。
'/'アクセス時は1ページ目を表示し
リンクを押下した場合は '/ページ番号'のアクセスになります。


サンプルの構造は以下。

-- app.js
-- public
    -- style.css
-- router
    -- index.js
-- views
    -- index.ejs

style.cssの紹介は省略します。


app.js

こちらはいつもと同じです。

var express = require('express');
var indexRouter = require('./router/index');

var app = express();
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.use('/', indexRouter);

var server = app.listen(3000, () => {
    console.log('Server Start!');
});


index.js

前回紹介したBookshelfを利用します。

nandakagoodvibes.hatenablog.com


var express = require('express');
var router = express.Router();

var knex = require('knex')({
    client: 'mysql',
    connection: {
                host     : 'ホスト',
                user     : 'ユーザー',
                password : 'パスワード',
                database : '対象のデータベース'
                charset  : 'utf8'
    }
});

var Bookshelf = require('bookshelf')(knex);

var MyData = Bookshelf.Model.extend({
    tableName: 'テーブル名'
});

router.get('/',(req, res, next) => {

    new MyData()
        .fetchPage({page: 1, pageSize: 3})
        .then((collection) => {
            var data = {
                title: 'INDEX',
                content: collection.toArray(),
                pagination: collection.pagination
            };

            res.render('index.ejs', data);
        })
        .catch((err) => {
            res.status(500).json({
                error: true,
                data: {message: err.message}
            });
        });
});

router.get('/:page',(req, res, next) => {

    var pg = req.params.page;
    pg *= 1;

    new MyData()
        .fetchPage({page: pg, pageSize: 3})
        .then((collection) => {
            var data = {
                title: 'INDEX',
                content: collection.toArray(),
                pagination: collection.pagination
            };

            res.render('index.ejs', data);
        })
        .catch((err) => {
            res.status(500).json({
                error: true,
                data: {message: err.message}
            });
        });
});

module.exports = router;


'/'にアクセスした場合は

router.get('/',(req, res, next) => {
...

にて1ページ目を表示する処理を行います。
リンクを押下された場合は

router.get('/:page',(req, res, next) => {
...

にて各ページ番号の表示の処理を行います。
fetchPageで指定したページ番号、レコード数のデータを取得し
テンプレート側に渡します。


index.ejs

データの表示を行います。
リンクはページ番号をつけて遷移を行うので
最初・最終ページの場合に前・後ページ移動のリンクが
おかしなページへ遷移しないよう考慮しています。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title><%= title %></title>
    <link rel='stylesheet' href='./style.css' />
</head>

<body>
    <head>
        <h1><%= title %></h1>
    </head>
    <div role="main">
        <table>
        <% for (var i in content) { %>
        <tr>
            <% var obj = content[i].attributes; %>
            <th><%= obj.id %></th>
            <td><%= obj.name %></td>
            <td><%= obj.mail %></td>
            <td><%= obj.age %></td>
        </tr>
        <% } %>
        </table>
    </div>
    <div>
        <span><a href="/1">&lt;&lt; 最初</a></span>
        |
        <% if (pagination.page == 1) { %>
            <span><a href="/<%= pagination.page %>">&lt;</a></span>
            ||
            <span><a href="/<%= pagination.page + 1 %>">&gt;</a></span>
        <% } else if (pagination.page == pagination.pageCount) { %>
            <span><a href="/<%= pagination.page - 1 %>">&lt;</a></span>
            ||
            <span><a href="/<%= pagination.page %>">&gt;</a></span>
        <% } else { %>
            <span><a href="/<%= pagination.page - 1 %>">&lt;</a></span>
            ||
            <span><a href="/<%= pagination.page + 1 %>">&gt;</a></span>
        <% } %>
        |
        <span><a href="/<%= pagination.pageCount %>">最後 &gt;&gt;</a></span>
    </div>
</body>
</html>

paginationの各値は以下の内容です。

  • pagination.page : 現在のページ番号
  • pagination.pageCount: ページ数
  • pagination.pageSize : 1ページあたりのレコード数
  • pagination.rawCount : レコード総数


まとめ

多くのデータを表示する場合は
ページネーションは必要になってきます。
今回の内容を参考にしていただけたら幸いです。
以上。