我有一个Golang服务器,它从数据库表中获取所有行。
SELECT * FROM people;
获取的数据被"封送"到 JSON 中:
json.NewEncoder(w).Encode(people)
JavaScript 可以通过其 Fetch API 获取行。
现在假设数据库表有 10,000 行,但我只想在屏幕上显示尽可能多的行。
当我滚动页面时,我希望从数据库中动态获取更多行。
客户端是否需要将数据发送到服务器,告诉服务器再次获取包含更多数据的 JSON?
如有任何建议,我将不胜感激。谢谢!
假设您要查找的是分页,那么答案非常简单,但它需要在客户端和服务器端进行更改:
获取数据:您希望客户端告诉服务器数据批次应该有多大(通常每次调用 10、20、30、40 或 50 个结果,默认值为 10(。
您希望从客户端获得的第二个参数是指示客户端已加载的结果数。
使用这两个值,您将能够丰富查询以包含限制和偏移值。默认偏移量为 0,默认限制为 10。
这意味着第一个查询将如下所示:
SELECT * FROM people LIMIT 10 OFFSET 0;
这通常缩短为LIMIT 10;
或LIMIT 0, 10;
.
现在,如果客户端向下滚动,要加载接下来的 10 条记录,您需要它们执行 AJAX 调用,为您提供批大小和偏移值(已显示的记录数(,然后只需插入这些值,您将获得:
SELECT * FROM people LIMIT 10 OFFSET 10;
此查询告知数据库跳过前 10 个结果,并返回下一个 10 个结果。
如果您使用的是实际页面,则处理此问题的另一种常见方法是让客户端提供页面大小值和页码。例如:我想每页看到 20 个人,我想直接从第 1 页跳到第 5 页,传递给服务器的参数将是这样的:page_size=20&page=5
这意味着我需要一个跳过前 80 条记录(20 乘以 4 页(的查询,这是一个微不足道的计算:
offset := pageNr * pageSize - pageSize // or (pageNr -1 ) * pageSize
对于查询:
SELECT * FROM people LIMIT 20 OFFSET 80;
一些一般提示:
- 尽可能避免
SELECT *
,始终明确您选择的字段。向表中添加字段很常见,使用select *
可能会导致公开您不希望人们看到的数据,或者您的代码因为无法处理新字段而搞砸 - 指定数据的顺序。在表中有一个
created_at
字段,并按该值排序,或按名称或其他方式排序。如果不以特定方式对结果进行排序,如何保证前 10 个结果始终相同?如果您不能保证这一点,为什么您不可能跳过一些记录,并显示其他记录两次? - 创建一个表示数据库中记录的
People
类型服务器端(如果尚未创建(
我已经很多年没有做过任何前端工作了,但是要知道何时需要加载更多记录,您需要编写一些处理scroll
事件的JS。已经有很多插件了,我的JS很可能已经过时了,但这里有一个尝试(未经测试,被视为伪代码(:
document.querySelector('#person_container').addEventListener('scroll', (function(ls) {
var last = ls[ls.length-1] // last person already loaded
let batchSize = ls.length // IIRC, let is used instead of var now
// returning the actual handler
return function(e) {
// scroll reached bottom of the page
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
// make AJAX call with batchSize + offset, append new elements after last element
}
};
}(document.querySelectorAll('.person_item')))