gorm-plus icon indicating copy to clipboard operation
gorm-plus copied to clipboard

提供一种基于流式分页的分页函数

Open ColorDreams opened this issue 2 years ago • 1 comments

在一些不需要跳页的场景下使用,相比于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)
	}
}

ColorDreams avatar Sep 14 '23 08:09 ColorDreams

在一些不需要跳页的场景下使用,相比于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)
	}
}

上一页有order,下一页怎么没有了?对于一些字段是无序的,很明显下一页与上一页结果应该不一致,会乱掉;另外order 也有可能是多个字段

0x457 avatar Nov 01 '23 12:11 0x457