Cài đặt thuật toán phân trang của EzyPlatform
Back To BlogsThuật toán phân trang sử dụng con trỏ
Hãy nói bạn có các bản ghi được sắp xếp theo thứ tự thế này:
Nhiệm vụ của chúng ta là sẽ phải lấy ra các trang dữ liệu, ví dụ mỗi trang sẽ có 3 phần tử, thuật toán phân trang của EzyPlatform sẽ được cài đặt như sau.
Lấy từ trang đầu
Khi bạn lấy từ trang đầu với 3 phần từ lúc này EzyPlatform sẽ thực hiện các bước trong thuật toán như sau:
Ở lần lấy đầu tiên- Client gửi lên
nextPageToken = null - Lấy ra 3 + 1 phần từ đầu tiên là [1, 2, 3, 4].
- Kiểm tra xem số phần từ lấy được có phải là 4 không, nếu đúng là 4 thì sẽ có trang kế tiếp, ngược lại thì không có trang kế tiếp.
- Có trang kế tiếp nên trả về
hasNext = truevàpageToken.next=3cho client. Lưu ý rằngpageToken.next=3chứ không phải bằng 4, vì nếu lấy bản ghi 4 thì ở lần lấy kế tiếp sẽ không biết có trang sau hay không. - Bởi vì đây là lấy trang đầu nên không có thông tin của
nextPageTokenđược gửi từ client nên trả về cho clienthasPrevious=falsevàpageToken.previous=null.
Kết quả trả về cho client sẽ là:
{
"items": [1, 2, 3],
"pageToken": {
"next": "3",
"previous": null
},
"continuation": {
"hasNext": true,
"hasPrevious": false
},
"count": 3,
"total": 9,
"timestamp": 1700380800000
}
- Client gửi lên
nextPageToken = 3 - Lấy ra 3 + 1 phần từ đầu tiên với điều kiện
>3là [4, 5, 6, 7]. - Kiểm tra xem số phần từ lấy được có phải là 4 không, nếu đúng là 4 thì sẽ có trang kế tiếp, ngược lại thì không có trang kế tiếp.
- Có trang kế tiếp nên trả về
hasNext = truevàpageToken.next=6cho client. - Vì có nhận được thông tin
nextPageTokenđược gửi từ client nên trả về cho clienthasPrevious=truevàpageToken.previous=4. Lưu ý phải trả vềpageToken.previous=4chứ không phải 3 vì nếu muốn lấy trang trước của 4 thì sẽ sử dụng điều kiện truy vấn< 4.
Kết quả trả về cho client sẽ là:
{
"items": [4, 5, 6],
"pageToken": {
"next": "6",
"previous": "4"
},
"continuation": {
"hasNext": true,
"hasPrevious": true
},
"count": 3,
"total": 9,
"timestamp": 1700380800000
}
- Client gửi lên
nextPageToken = 6 - Lấy ra 3 + 1 phần từ đầu tiên với điều kiện
>3là [7, 8, 9]. - Vì chỉ có 3 phần tử lấy được thay vì 4 nên không có trang kế tiếp.
- Không có trang kế tiếp nên trả về
hasNext = falsevàpageToken.next=nullcho client. - Vì có nhận được thông tin
nextPageTokenđược gửi từ client nên trả về cho clienthasPrevious=truevàpageToken.previous=7.
Kết quả trả về cho client sẽ là:
{
"items": [7, 8, 9],
"pageToken": {
"next": null,
"previous": "7"
},
"continuation": {
"hasNext": false,
"hasPrevious": true
},
"count": 3,
"total": 9,
"timestamp": 1700380800000
}
Lấy từ trang cuối
Khi bạn lấy từ trang đầu với 3 phần từ lúc này EzyPlatform sẽ thực hiện các bước trong thuật toán như sau:
Ở lần lấy đầu tiên- Client gửi lên
prevPageToken = nullvàlastPage=true. - Lấy ra 3 + 1 phần từ cuối cùng là [9, 8, 7, 6].
- Kiểm tra xem số phần từ lấy được có phải là 4 không, nếu đúng là 4 thì sẽ có trang kế sau, ngược lại thì không có trang sau.
- Có trang sau nên trả về
hasPrevious = truevàpageToken.previous=7cho client. - Bởi vì đây là lấy trang đầu nên không có thông tin của
prevPageTokenđược gửi từ client nên trả về cho clienthasNext=falsevàpageToken.next=null. - Đảo ngược thứ tự các phần tử kết quả thành [7, 8, 9].
Kết quả trả về cho client sẽ là:
{
"items": [7, 8, 9],
"pageToken": {
"next": null,
"previous": "7"
},
"continuation": {
"hasNext": false,
"hasPrevious": true
},
"count": 3,
"total": 9,
"timestamp": 1700380800000
}
- Client gửi lên
prevPageToken = 7 - Lấy ra 3 + 1 phần từ đầu tiên với điều kiện
<7là [6, 5, 4, 3]. - Số phần tử lấy ra được là 4 nên có trang sau.
- Có trang sau nên trả về
hasPrevious = truevàpageToken.previous=4cho client. - Vì có nhận được thông tin
prevPageTokenđược gửi từ client nên trả về cho clienthasNext=truevàpageToken.next=7. - Đảo ngược thứ tự các phần tử kết quả thành [4, 5, 6].
Kết quả trả về cho client sẽ là:
{
"items": [4, 5, 6],
"pageToken": {
"next": "6",
"previous": "4"
},
"continuation": {
"hasNext": true,
"hasPrevious": true
},
"count": 3,
"total": 9,
"timestamp": 1700380800000
}
- Client gửi lên
prevPageToken = 4 - Lấy ra 3 + 1 phần từ đầu tiên với điều kiện
<4là [3, 2, 1]. - Vì chỉ có 3 phần tử lấy được thay vì 4 nên không có trang sau.
- Không có trang sau nên trả về
hasPrevious = falsevàpageToken.previous=nullcho client. - Vì có nhận được thông tin
prevPageTokenđược gửi từ client nên trả về cho clienthasNext=truevàpageToken.next=3. - Đảo ngược thứ tự các phần tử kết quả thành [1, 2, 3].
Kết quả trả về cho client sẽ là:
{
"items": [1, 2, 3],
"pageToken": {
"next": "3",
"previous": null
},
"continuation": {
"hasNext": true,
"hasPrevious": false
},
"count": 3,
"total": 9,
"timestamp": 1700380800000
}
Thuật toán phân trang sử dụng offset, limit
Thuật toán này cũng chung cơ chế page token như phân trang sử dụng con trỏ, tuy nhiên nó cũng có 2 điểm khác biệt.
- Khi truy vấn sẽ sử dụng
offsetthay vì điều kiện so sánh. - Đối với tình huống người dùng lấy từ trang cuối nó sẽ cần lấy ra tổng số bản ghi trừ đi số bản ghi cần lấy
totalRecords - limitđể tính ra được offset.
Tổng kết lại
Thuật toán cài đặt phân trong trong EzyPlatform cũng không quá phức tạp, điều quan trọng là một loạt các thiết kế và kỹ thuật lập trình đưa ra để sử dụng thuật toán này sao cho hiệu quả và mã nguồn được tái sử dụng nhiều nhất thay vì lặp đi lặp lại cho mỗi nghiệp vụ phân trang.