JSON数据接口实现分页查询需要结合参数设计、数据库优化、响应格式规范等多个环节,以下是系统化的实现方案及最佳实践:
参数类型 | 示例 | 适用场景 | 优缺点 |
---|---|---|---|
Offset-Limit | ?limit=10&page=3 | 通用场景,简单易用 | 大数据量时性能较差16 |
Cursor-Based | ?cursor=id&limit=10 | 实时数据流、高性能分页 | 无法随机跳页8 |
时间范围 | ?since=2023-01-01 | 时间序列数据(如日志) | 依赖时间字段有序性 |
GET /articles?page[limit]=10&page[offset]=20
// MongoDB分页查询(Offset模式)
app.get('/api/users', async (req, res) => {
const limit = parseInt(req.query['page[limit]'] || 10);
const offset = parseInt(req.query['page[offset]'] || 0);
// 索引优化:确保排序字段有索引
const users = await User.find()
.sort({ createdAt: -1 })
.skip(offset)
.limit(limit);
const total = await User.countDocuments();
res.json({
data: users,
meta: {
total,
limit,
offset,
totalPages: Math.ceil(total / limit)
}
});
});
// MongoDB游标分页(基于ID)
app.get('/api/users', async (req, res) => {
const lastId = req.query.lastId;
const limit = parseInt(req.query.limit || 10);
const query = lastId ? { _id: { $gt: lastId } } : {};
const users = await User.find(query).sort({ _id: 1 }).limit(limit);
res.json({ data: users });
});
function Pagination({ currentPage, totalPages, onPageChange }) {
return (
<div>
<button
onClick={() => onPageChange(currentPage - 1)}
disabled={currentPage === 1}
>
上一页
</button>
<span>{currentPage}/{totalPages}</span>
<button
onClick={() => onPageChange(currentPage + 1)}
disabled={currentPage === totalPages}
>
下一页
</button>
</div>
);
}
function UserList() {
const [users, setUsers] = useState([]);
const [pagination, setPagination] = useState({
page: 1,
limit: 10,
total: 0
});
useEffect(() => {
fetch(`/api/users?page[limit]=${pagination.limit}&page[offset]=${(pagination.page-1)*pagination.limit}`)
.then(res => res.json())
.then(data => {
setUsers(data.data);
setPagination(prev => ({
...prev,
total: data.meta.total
}));
});
}, [pagination.page, pagination.limit]);
return (
<>
{users.map(user => <div key={user.id}>{user.name}</div>)}
<Pagination
currentPage={pagination.page}
totalPages={Math.ceil(pagination.total / pagination.limit)}
onPageChange={page => setPagination(prev => ({ ...prev, page }))}
/>
</>
);
}
2. 缓存机制
3. 游标分页替代Offset