Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
PhoenixL0911 opened this issue Sep 14, 2023 · 1 comment
Open

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

PhoenixL0911 opened this issue Sep 14, 2023 · 1 comment
Labels
enhancement New feature or request

Comments

@PhoenixL0911
Copy link
Contributor

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

0x457 commented Nov 1, 2023

在一些不需要跳页的场景下使用,相比于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 也有可能是多个字段

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants