数据库入门:g.DB() 配置、模型与简单查询
引言
业务数据总要落库。GoFrame 的数据访问层 gdb(ORM)支持 MySQL、PostgreSQL、SQLite 等多种数据库,通过配置声明连接,用链式 API 操作表。本章从配置到第一条查询。
概念
- 数据库配置:
config.yaml中database节点按"分组名"配置,默认分组名为default。 - 连接串 link:形如
账号:密码@tcp(主机:端口)/库名,type 指定数据库类型。 - 获取对象:
g.DB()获取默认分组,g.DB("分组名")获取指定分组;均返回 gdb.DB 接口。 - 模型 Model:
g.DB().Model("表名")得到一个可链式调用的模型对象;查询以结构体或记录(Record/Result)承载结果。 - 上下文:链式查询的 ctx 通过
.Ctx(ctx)传入(官方文档示例中也有把 ctx 作为末端参数的写法,以官方文档为准)。
代码示例
先配置连接(以 MySQL 为例):
database:
default:
type: "mysql"
link: "root:12345678@tcp(127.0.0.1:3306)/demo"
debug: true # 开启后控制台打印执行的 SQL,方便学习
假设表 user(id/name/age/status),查询示例:
package main
import (
"fmt"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
)
func main() {
ctx := gctx.New()
db := g.DB() // 默认分组
// 1. 查询单条记录到结构体
var user struct {
Id int
Name string
}
err := db.Model("user").Ctx(ctx).Where("id", 1).Scan(&user)
if err != nil {
panic(err)
}
fmt.Printf("user: %+v\n", user)
// 2. 查询多条记录(List 结构)
list, err := db.Model("user").Ctx(ctx).Where("status", 1).All()
if err != nil {
panic(err)
}
for _, record := range list {
fmt.Println(record["id"], record["name"])
}
// 3. 查询单个值
name, err := db.Model("user").Ctx(ctx).Where("id", 1).Value("name")
if err != nil {
panic(err)
}
fmt.Println("name =", name.String())
}
把查询封装进规范路由的接口里也很直接(controller 风格):
type UserGetRes struct {
Id int `json:"id"`
Name string `json:"name"`
}
func (User) Get(ctx context.Context, req *UserGetReq) (res *UserGetRes, err error) {
var out UserGetRes
err = g.DB().Model("user").Ctx(ctx).Where("id", req.Id).Scan(&out)
if err != nil {
return nil, err
}
return &out, nil
}
注意点
- 链式方法顺序自由,但末端查询方法(Scan/All/One 等)执行后模型不可复用,注意链式对象的作用域。
Scan的目标必须是指针;查不到数据时返回空结果而非报错,用record.IsEmpty()或 err 为 nil + 空判断。link中密码含特殊字符时注意转义;生产库务必最小权限账号。debug: true只建议开发环境开启,否则 SQL 会全部打进日志。
小结
从 database 配置到 g.DB().Model(...).Scan(...),GoFrame 的 ORM 五分钟即可跑通。下一章展开链式操作的条件、排序、分页与分组。ORM 能力全景以官方文档 goframe.org 的 gdb 章节为准。