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 为准。

笔记加载中…