model.go
package database
import (
"gorm.io/gorm"
)
type Page[T any] struct {
CurrentPage int64
PageSize int64
Total int64
Pages int64
Data []T
}
func (page *Page[T]) SelectPage(wrapper map[string]interface{}) (e error) {
e = nil
var model T
DB.Model(&model).Where(wrapper).Count(&page.Total)
if page.Total == 0 {
page.Data = []T{}
return
}
e = DB.Model(&model).Where(wrapper).Scopes(Paginate(page)).Find(&page.Data).Error
return
}
func Paginate[T any](page *Page[T]) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
if page.CurrentPage <= 0 {
page.CurrentPage = 0
}
switch {
case page.PageSize > 100:
page.PageSize = 100
case page.PageSize <= 0:
page.PageSize = 10
}
page.Pages = page.Total / page.PageSize
if page.Total%page.PageSize != 0 {
page.Pages++
}
p := page.CurrentPage
if page.CurrentPage > page.Pages {
p = page.Pages
}
size := page.PageSize
offset := int((p - 1) * size)
return db.Offset(offset).Limit(int(size))
}
}
mysql.go
package database
import (
// 导入gorm工具包
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
var DB *gorm.DB
func Close() {
db, _ := DB.DB()
db.Close()
}
func InitMysql() error {
dsn := "root:fuck@you@tcp(127.0.0.1:3306)/world?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
Logger: logger.Default.LogMode(logger.Info),
})
if err != nil {
return err
}
DB = db
return nil
}
DEMO:
city.go
package model
import (
"gorm_page_generic/database"
)
type CityQueryInfo struct {
PageInfo
CountryCode string `json:"countryCode"`
District string `json:"district"`
}
type City struct {
ID int `json:"id"`
Name string `json:"name"`
CountryCode string `json:"countryCode"`
District string `json:"district"`
Population int `json:"population"`
}
func (c *City) TableName() string {
return "city"
}
func (c *City) SelectPageList(p *database.Page[City], wrapper map[string]interface{}) error {
return p.SelectPage(wrapper)
}
调用使用
type CityService struct{}
var cityModel model.City
// 使用泛型调用分页查询
func (c *CityService) SelectPageList(queryVo model.CityQueryInfo) (*model.PageResponse[model.City], error) {
p := &database.Page[model.City]{
CurrentPage: queryVo.CurrentPage,
PageSize: queryVo.PageSize,
}
wrapper := make(map[string]interface{}, 0)
if queryVo.CountryCode != "" {
wrapper["CountryCode"] = queryVo.CountryCode
}
if queryVo.District != "" {
wrapper["District"] = queryVo.District
}
err := cityModel.SelectPageList(p, wrapper)
if err != nil {
return nil, err
}
pageResponse := model.NewPageResponse(p)
return pageResponse, err
}