ORM 链式操作:Where/Order/分页/Group 常用写法
引言
上一章学会了 Model 与简单查询。真实查询往往要拼条件、排序、分页、分组统计,gdb 把这些都做成了可读性很好的链式方法。本章讲解最常用的一组。
概念
gdb 模型对象的常用链式方法(方法签名以官方文档 gdb 链式操作章节为准):
- 条件:
Where("字段", 值)、Where("字段 > ?", 值)、WhereOr(...)追加 OR 条件,多条件可传g.Map。 - 排序:
OrderAsc("字段")、OrderDesc("字段")、Order("字段 asc, 字段 desc")。 - 分页:
Limit(start, size)控制偏移与条数;按第 N 页换算Limit((n-1)*size, size)(若使用框架提供的便捷分页方法,以官方文档为准)。 - 分组统计:
Group("字段")配合Fields("字段, count(*) as total")。 - 字段与数量:
Fields(...)限定返回列,Count()取总数。 - 末端查询:
All()多行、One()单行、Scan(&dst)扫入结构体/切片。
代码示例
条件与排序:
package main
import (
"fmt"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
)
func main() {
ctx := gctx.New()
m := g.DB().Model("user").Ctx(ctx)
// 精确条件 + 降序
list, err := m.Where("status", 1).
Where("age > ?", 18).
OrderDesc("id").
All()
if err != nil {
panic(err)
}
for _, rec := range list {
fmt.Println(rec["id"], rec["name"])
}
// OR 条件 + 多条件 Map
m2 := g.DB().Model("user").Ctx(ctx)
list2, err := m2.Where(g.Map{
"status": 1,
}).WhereOr("name", "admin").All()
_ = list2
// 分页:第 2 页,每页 10 条(Limit 的起始/条数顺序以官方文档为准)
m3 := g.DB().Model("user").Ctx(ctx)
page, size := 2, 10
list3, err := m3.Where("status", 1).
OrderAsc("id").
Limit((page-1)*size, size).
All()
_ = list3
// 总数与分页数据配合
total, err := g.DB().Model("user").Ctx(ctx).Where("status", 1).Count()
fmt.Println("total =", total)
}
分组统计(例如按状态统计用户数):
stats, err := g.DB().Model("user").Ctx(ctx).
Fields("status, count(*) as total").
Group("status").
All()
if err != nil {
panic(err)
}
for _, rec := range stats {
fmt.Println("status:", rec["status"], "total:", rec["total"])
}
注意点
Where中的?是占位符,值作为后续参数传入,框架会做参数化处理,避免拼 SQL 注入。- 每个查询建议从
Model重新开始链式构建,避免复用上次的条件状态。 All/One返回 Record/Result,读取用列名字符串;想要强类型就用Scan扫到结构体或结构体切片。- 分页换算、
Limit参数顺序在不同版本可能有差异,写代码时对照所用版本文档确认一次。
小结
Where 定条件、Order 定顺序、Limit 定分页、Group 做统计,加上 Count 配套,覆盖了日常 90% 的查询。下一章看写操作:Insert/Update/Delete。链式方法完整清单以官方文档 goframe.org 为准。