Open
Description
在一些不需要跳页的场景下使用,相比于offset具有更好的性能。
伪代码如下:
type Comparable interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~float32 | ~float64 | time.Time
}
type StreamingPage[T any, V Comparable] struct {
Column string `json:"column"` // 进行分页的列字段
StartValue T `json:"startValue"` // 分页起始值
Limit int `json:"limit"` // 页大小
Forward bool `json:"forward"` // 上下页翻页标识
Total int64 `json:"total"` // 总记录数
Records []*T `json:"records"` // 查询记录
RecordsMap []T `json:"recordsMap"` // 查询记录Map
}
// StreamingPaginate 流式分页,根据自增ID、雪花ID、时间等数值类型或者时间类型分页
// Tips: 相比于 offset 分页性能更好,走的是 range,缺点是没办法跳页查询
func StreamingPaginate[T any, V Comparable](p *StreamingPage[T, V]) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
// 下一页
if p.Forward {
return db.Where(fmt.Sprintf("%v > ?", p.Column), p.StartValue).Limit(p.Limit)
}
// 上一页
return db.Where(fmt.Sprintf("%v < ?", p.Column), p.StartValue).Order(fmt.Sprintf("%v DESC", p.Column)).Limit(p.Limit)
}
}