GORM是什么?
The fantastic ORM library for Golang aims to be developer friendly.
特性
全功能 ORM
关联 (Has One,Has Many,Belongs To,Many To Many,多态,单表继承)
Create,Save,Update,Delete,Find 中钩子方法
支持 Preload、Joins 的预加载
事务,嵌套事务,Save Point,Rollback To Saved Point
Context、预编译模式、DryRun 模式
批量插入,FindInBatches,Find/Create with Map,使用 SQL 表达式、Context Valuer 进行 CRUD
SQL 构建器,Upsert,数据库锁,Optimizer/Index/Comment Hint,命名参数,子查询
复合主键,索引,约束
Auto Migration
自定义 Logger
灵活的可扩展插件 API:Database Resolver(多数据库,读写分离)、Prometheus…
每个特性都经过了测试的重重考验
开发者友好
通过本文你会知道如何封装一个GORM通用的分页查询组件。下面上代码
scopes/page.go
package scopes
import (
"gorm.io/gorm"
"kphx/core/storage/mysql"
"kphx/core/storage/mysql/page"
)
// Page Usage: db.Scopes(Page(r)).Find(&users)
func Page(page *page.Page) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
// New connection
newDB := mysql.BaseDB
// paging length
switch {
case page.Size == nil || *page.Size <= 0:
size := 10
page.Size = &size
}
// current length
switch {
case page.Current == nil:
current := 1
page.Current = ¤t
}
offset := (*page.Current - 1) * *page.Size
var total int64
newDB.Statement = db.Statement // 取DB的statement
newDB.Count(&total)
page.Total = &total
return db.Offset(offset).Limit(*page.Size)
}
}
/page/page.go
package page
// Page 通用分页
// @Description 通用分页查条件
type Page struct {
Current *int `json:"current" form:"current" bind:"numeric"` // 当前页,默认为1
Size *int `json:"size",form:"size" bind:"numeric"` // 分页条目数据,默认10
Total *int64 `json:"total"` // 查询总数量
}
func (page *Page) Data(data interface{}) *Pages {
pages := Pages{Page: *page, Records: data}
return &pages
}
page/Pages.go
package page
// Pages 分页查询返回
// @Description 分页查询返回
type Pages struct {
Page Page `json:"pages"` // 分页信息
Records interface{} `json:"records"` // 返回数据
}
packege main
func main() {
page := page.Page{} // 默认在第1页取10条
data := param.GetByPage(&page)
}
func GetByPage(page *pages.ParamPage) *page.Pages {
db := mysql.BaseDB.Session(&gorm.Session{NewDB: true}) // 必须要这样写,官方文件或Github issues 有说明。
if len(page.Code) > 0 {
db = db.Where("code like ?", "%"+page.Code+"%")
}
var records *[]entity.Param
if err := db.Scopes(scopes.Page(&page.Page)).Find(&records).Error; err != nil {
fmt.Println(err)
}
return page.Data(records)
}
Scopes(scopes.Page(&page.Page))
放在最后
返回结果
{
"code": 0,
"message": "Success.",
"data": {
"pages": {
"current": 1,
"size": 10,
"total": 3
},
"records": [
{
"id": "1625038713857773568",
"code": "app.debug1",
"value": "true",
"desc": "",
"Status": 0,
"CreateAt": 1676274395,
"ModifyAt": 1676274395
},
{
"id": "1625039709522628608",
"code": "app.debug2",
"value": "true",
"desc": "",
"Status": 0,
"CreateAt": 1676274633,
"ModifyAt": 1676274633
},
{
"id": "1625039725968494592",
"code": "app.debug3",
"value": "true",
"desc": "",
"Status": 0,
"CreateAt": 1676274637,
"ModifyAt": 1676274637
}
]
}
}
结果包含其它代码逻辑,这里就不一一列出,想知道更多,请访问我的博客.