我想得到并提供响应中的total_record_count,page_number,page_size,total_pages,has_more信息,并且能够对结果进行分页,因为我将查询限制为100.最好的方法是什么?
这是我目前的设置:
router.get('/?', function(req, res, next) {
const sql = "SELECT * from users ";
const existingParams = ["title", "active"].filter(field => req.query[field]);
if (existingParams.length) {
sql += " WHERE ";
sql += existingParams.map(field => `${field} = ?`).join(" AND ");
sql += " LIMIT 100 ";
}
connection.query(
sql,
existingParams.map(field => req.query[field]),
function (error, results, fields) {
res.json({"status": 200, "error": null, "total_record_count": 604, "page_number": 1, "page_size": 100, "total_pages": 7, "has_more": true, "records": results});
}
);
});
在url中,如果total_record_count超过LIMIT,我希望能够提供/允许页面参数'p'。因此查询参数p指定要返回的页面,从1开始。如果省略p参数,则默认值为1. Sth like:
http://localhost:4001/api/v1/users/?active=0&title=mr&p=1
答案 0 :(得分:1)
MySQL LIMIT需要2个值,offset&行数。操作这些就是你当然可以做分页的方法。
例如。如果说每页有10个记录长。
第1页= LIMIT 0, 10
第2页= LIMIT 10, 10
第3页= LIMIT 20, 10
等。
IOW:LIMIT (pageNo - 1) * PageSize, PageSize
现在使用限制的一个问题是recordcount用于结果集,IOW:有限的10条记录。
但是你可以做的是要求MySQL存储如果未应用LIMIT,记录计数将会是多少。您可以通过在SQL前面添加SQL_CALC_FOUND_ROWS来检索它。
例如。 SELECT SQL_CALC_FOUND_ROWS * FROM TABLE WHERE something LIMIT 10, 10
然后,您可以执行另一个检索此值的查询。
SELECT FOUND_ROWS();
答案 1 :(得分:1)
对于分页,您需要在MySQL中查询类似下面的查询
SELECT * FROM users LIMIT 0,10
使用两个参数,第一个参数指定要返回的第一行的偏移量,第二个参数指定要返回的最大行数。初始行的偏移量为0(不是1)。
您希望将默认值设为第1页和100结果
router.get('/?', function(req, res, next) {
const sql = "SELECT * from users ";
const existingParams = ["title", "active"].filter(field => req.query[field]);
const pageNum = req.query.p || 1;
const pageSize = req.query.p_size || 100;
if (existingParams.length) {
sql += " WHERE ";
sql += existingParams.map(field => `${field} = ?`).join(" AND ");
}
sql += ` LIMIT ${(pageNum - 1) * PageSize},${PageSize}`;
...
});
对于关于提供总行数的第二个问题,您需要为此运行两个查询。您可以在mysql> 4.0中使用SQL_CALC_FOUND_ROWS and FOUND_ROWS()。但是当我们在查询中为WHERE / ORDER子句提供适当的索引时,使用两个单独的查询而不是SQL_CALC_FOUND_ROWS的查询要快得多(一个用于数据,一个用于获取所有行数)。
现在你必须同时运行两个查询以提高性能,所以使用回调你可以利用我为并行运行回调而编写的this function并等到所有回调都完成。或者你可以在这里使用promisified MySQL库,或者你可以使用Bluebird使你的当前库得到宣传。
像这样:
const connection = mysql.createConnection({.....});
global.db = Bluebird.promisifyAll(connection);
db.queryAsync("SELECT * FROM users")
.then(function(rows){
console.log(rows);
})
然后像这样运行查询
Promise.all([
db.queryAsync("SELECT * FROM users WHERE title='ridham' LIMIT 0,10"), // generated by your code
db.queryAsync("SELECT COUNT(*) FROM users WHERE title='ridham'")
]).then(([data, count]) => {
// your logic to send response
})
或者您也可以运行以下查询,也可以运行
SELECT * FROM 'table' JOIN (SELECT COUNT(*) FROM 'table') t2 WHERE title='ridham' LIMIT 0,10")
此外,您可以使用Sequilize或Waterline之类的ORM。这至少会使你对MYSQL更容易10倍。
作为sequilize的例子:
User.findAndCountAll({
where: {
title: {
[Op.like]: 'ridham'
}
},
offset: 10,
limit: 2
})
.then(result => {
console.log(result.count);
console.log(result.rows);
});