GoFrame 实战:XYGo Admin 数据库配置与 DAO 三层模型操作指南
GoFrame 实战:XYGo Admin 数据库配置与 DAO 三层模型操作指南
在基于 GoFrame 的后台管理系统开发中,数据库操作是最核心的能力之一。本文以 XYGo Admin 为例,详细讲解 GoFrame 框架下的数据库配置、DAO/Entity/DO 三层数据模型,以及 MySQL 与 PostgreSQL 双数据库方言适配的落地实践。
一、数据库基础配置
XYGo Admin 同时支持 MySQL 和 PostgreSQL,切换只需修改 `server/manifest/config/config.yaml` 文件中的数据库连接字符串。
MySQL 配置:
```yaml
database:
default:
link: "mysql:root:123456@tcp(127.0.0.1:3306)/xygoadmin?charset=utf8mb4&parseTime=true&loc=Local"
debug: true
prefix: "xy_"
```
PostgreSQL 配置:
```yaml
database:
default:
link: "pgsql:postgres:123456@tcp(127.0.0.1:5432)/xygoadmin"
debug: true
prefix: "xy_"
```
项目提供两套独立的建表脚本:`mysql_install.sql` 和 `pgsql_install.sql`,选定数据库后只需导入对应的脚本即可完成初始化。
二、DAO / Entity / DO 三层模型
GoFrame 的数据操作采用经典的三层模型,代码通过 `gf gen dao` 命令自动生成,开发者无需手写冗长的数据库映射代码。
Entity(实体层)
位于 `model/entity/` 目录,是数据库表结构的一对一映射,每个字段与数据表列精确对应,开发者不应手动修改:
```go
// model/entity/admin_user.go(自动生成,勿修改)
type AdminUser struct {
Id uint64 `json:"id" orm:"id"`
Username string `json:"username" orm:"username"`
Password string `json:"password" orm:"password"`
Status int `json:"status" orm:"status"`
CreatedAt uint64 `json:"createdAt" orm:"created_at"`
}
```
DO(数据操作对象层)
位于 `model/do/` 目录,所有字段类型统一为 `any`,专门用于 `Where` 和 `Data` 参数,支持按需传入:
```go
// model/do/admin_user.go(自动生成)
type AdminUser struct {
Id interface{}
Username interface{}
Password interface{}
Status interface{}
}
```
使用时只需传入非零值,GoFrame 自动忽略空字段:
```go
dao.AdminUser.Ctx(ctx).Where(do.AdminUser{
Username: "admin",
Status: 1,
}).One()
```
DAO(数据访问层)
分为两部分:`dao/internal/` 目录是自动生成的基础实现(含表名、字段常量、`Ctx()` 方法),`dao/` 目录是可扩展的自定义层:
```go
// dao/admin_user.go(可扩展)
type adminUserDao struct { *internal.AdminUserDao }
var AdminUser = adminUserDao{internal.NewAdminUserDao()}
// 添加自定义查询方法
func (d *adminUserDao) FindByUsername(ctx context.Context, username string) (*entity.AdminUser, error) {
var user entity.AdminUser
err := d.Ctx(ctx).Where("username", username).Scan(&user)
return &user, err
}
```
这种双层设计兼顾了自动生成的效率与人工定制的灵活性——即使重新执行 `gf gen dao` 覆盖了 `internal/` 目录,自定义方法仍然安全保留。
三、常用数据库操作
```go
// 查询单条记录
user, err := dao.AdminUser.Ctx(ctx).Where("id", 1).One()
// 列表查询
users, err := dao.AdminUser.Ctx(ctx).
Where("status", 1).
OrderDesc("id").
Limit(10).
All()
// 条件 Count
count, err := dao.AdminUser.Ctx(ctx).
Where(do.AdminUser{Status: 1}).
Count()
// 插入数据
id, err := dao.AdminUser.Ctx(ctx).Insert(do.AdminUser{
Username: "newuser",
Password: "hashed_pwd",
Status: 1,
})
// 更新数据
_, err := dao.AdminUser.Ctx(ctx).
Where("id", 1).
Update(do.AdminUser{Status: 0})
// 事务操作
err := dao.AdminUser.Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
_, err := tx.Insert("admin_user", g.Map{"username": "tx_user"})
return err
})
```
四、MySQL 与 PostgreSQL 方言适配
XYGo Admin 通过 `library/dbdialect/` 包优雅地处理两种数据库的差异,代码生成器在创建表和同步字段时自动选择正确的语法:
| 差异点 | MySQL | PostgreSQL |
|--------|-------|-----------|
| 自增主键 | `AUTO_INCREMENT` | `SERIAL / BIGSERIAL` |
| 布尔类型 | `TINYINT(1)` | `BOOLEAN` |
| JSON 存储 | `JSON` | `JSONB` |
| 字符串引号 | 反引号 `` ` `` | 双引号 `"` |
| 时间戳 | `BIGINT` | `BIGINT` |
代码生成器(`gf gen dao`)会根据 `server/hack/config.yaml` 中的连接字符串自动识别数据库类型,开发者几乎无需关心底层差异:
```yaml
gfcli:
gen:
dao:
link: "mysql:root:123456@tcp(127.0.0.1:3306)/xygoadmin"
removePrefix: "xy_"
jsonCase: "CamelLower"
```
五、生产实践建议
1. 不要混用数据库:选定 MySQL 或 PostgreSQL 后应在项目生命周期内保持一致,切换后需重新导入建表脚本。
2. 善用 DO 层:在 `Where` 和 `Data` 方法中优先使用 `do.AdminUser{}` 结构体而非 `g.Map`,可获得编译期类型检查。
3. 自定义 DAO 方法:在 `dao/` 层(非 `internal/`)添加业务相关查询方法,避免在 Controller 中直接拼接查询条件。
4. 事务处理:建议使用 `dao.XXX.Transaction` 而非手动 `Begin/Commit/Rollback`,更简洁且不易遗漏提交。
> 本文基于 XYGo Admin 开发文档整理,完整源码与文档可访问 官网 查看。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)