数据库入门:g.DB() 配置、模型与简单查询

引言

业务数据总要落库。GoFrame 的数据访问层 gdb(ORM)支持 MySQL、PostgreSQL、SQLite 等多种数据库,通过配置声明连接,用链式 API 操作表。本章从配置到第一条查询。

概念

  • 数据库配置:config.yamldatabase 节点按"分组名"配置,默认分组名为 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 章节为准。

笔记加载中…