ページングの実装
よくあるページングの実装を実装してみました。DB内にはid500までの500レコード入っています。今回はMySQLを使います。
発行されるSQLは LIMIT 0, 10
となっていますが、 LIMIT 10 OFFSET 0
と同じ意味です。
findAllの引数にlimitとoffsetを指定してページングをしています。orderも指定するようにしましょう。
const PAGE_NUM = 10;
const getUsers = (page)=>{
return new Promise((resolve, reject)=>{
db.User.findAll({
limit: PAGE_NUM,
offset: PAGE_NUM * page,
order: [['id', 'ASC']],
raw: true
}).then((users)=>{
db.sequelize.close();
resolve({users: users});
}).catch((error)=>{
db.sequelize.close();
reject(error);
})
});
}
getUsers(0).then((users)=>{
console.log(users);
});
最初のページ
SELECT `id`, `name`, `createdAt`, `updatedAt`
FROM `Users` AS `User`
ORDER BY `User`.`id` ASC
LIMIT 0, 10;
{ users:
[ { id: 1,
name: 'name-1',
createdAt: 2018-03-23T15:18:49.000Z,
updatedAt: 2018-03-23T15:18:49.000Z },
{ id: 2,
name: 'name-33',
createdAt: 2018-03-23T15:18:49.000Z,
updatedAt: 2018-03-23T15:18:49.000Z },
・
・
・
{ id: 10,
name: 'name-36',
createdAt: 2018-03-23T15:18:50.000Z,
updatedAt: 2018-03-23T15:18:50.000Z } ] }
最後のページ
SELECT `id`, `name`, `createdAt`, `updatedAt`
FROM `Users` AS `User`
ORDER BY `User`.`id` ASC
LIMIT 490, 10;
{ users:
[ { id: 491,
name: 'name-38',
createdAt: 2018-03-24T03:12:18.000Z,
updatedAt: 2018-03-24T03:12:18.000Z },
{ id: 492,
name: 'name-39',
createdAt: 2018-03-24T03:12:18.000Z,
updatedAt: 2018-03-24T03:12:18.000Z },
・
・
・
{ id: 500,
name: 'name-30',
createdAt: 2018-03-24T03:12:18.000Z,
updatedAt: 2018-03-24T03:12:18.000Z } ] }
次のページが存在するかの情報も返す場合
APIなどで次のページがあるのかフラグを渡す場合
方針としては 1ページの要素数+1個 をLIMITで取得して 1ページの要素数+1個 返ってきたらtrue、それよりも少なければfalseにします。
また、返すデータとしてはsliceで1ページの要素数分のみ返すようにします。
const PAGE_NUM = 10;
const getUsers = (page)=>{
return new Promise((resolve, reject)=>{
db.User.findAll({
limit: PAGE_NUM + 1,
offset: PAGE_NUM * page,
order: [['id', 'ASC']],
raw: true
}).then((users)=>{
db.sequelize.close();
resolve({users: users.slice(0, PAGE_NUM), nextPage: users.length > PAGE_NUM});
}).catch((error)=>{
db.sequelize.close();
reject(error);
})
});
}
getUsers(0).then((users)=>{
console.log(users);
});
最初のページ
getUsersに0を指定した時です。
SELECT `id`, `name`, `createdAt`, `updatedAt`
FROM `Users` AS `User`
ORDER BY `User`.`id` ASC
LIMIT 0, 11;
{ users:
[ { id: 1,
name: 'name-1',
createdAt: 2018-03-23T15:18:49.000Z,
updatedAt: 2018-03-23T15:18:49.000Z },
{ id: 2,
name: 'name-33',
createdAt: 2018-03-23T15:18:49.000Z,
updatedAt: 2018-03-23T15:18:49.000Z },
・
・
・
{ id: 10,
name: 'name-36',
createdAt: 2018-03-23T15:18:50.000Z,
updatedAt: 2018-03-23T15:18:50.000Z } ],
nextPage: true }
最後のページ
getUsersに49を指定した時です。ちゃんとnextPageの値がfalseになっています。
SELECT `id`, `name`, `createdAt`, `updatedAt` FROM `Users` AS `User` ORDER BY `User`.`id` ASC LIMIT 490, 11;
{ users:
[ { id: 491,
name: 'name-38',
createdAt: 2018-03-24T03:12:18.000Z,
updatedAt: 2018-03-24T03:12:18.000Z },
{ id: 492,
name: 'name-39',
createdAt: 2018-03-24T03:12:18.000Z,
updatedAt: 2018-03-24T03:12:18.000Z },
・
・
・
{ id: 500,
name: 'name-30',
createdAt: 2018-03-24T03:12:18.000Z,
updatedAt: 2018-03-24T03:12:18.000Z } ],
nextPage: false }