告别手动CRUD:用Goframe CLI工具5分钟搞定数据库表到Service的完整代码生成

在快节奏的互联网开发中,时间就是竞争力。当产品经理突然提出"明天要上线一个用户积分系统"时,传统的手工编写CRUD代码往往会让开发者陷入无意义的重复劳动。Goframe框架的CLI工具链正是为解决这一痛点而生——它能让开发者从数据库设计到API接口的完整链路,在5分钟内生成符合规范的生产级代码。

1. 环境准备与项目初始化

工欲善其事,必先利其器。确保你的开发环境已安装:

# 检查Go版本(要求1.15+)
go version

# 安装Goframe CLI工具
go install github.com/gogf/gf/cmd/gf@latest

新建项目时,根据不同的初始化场景选择对应命令:

  • 全新项目gf init my-project 创建标准目录结构
  • 已有目录:在项目根目录执行 gf init . 初始化配置
  • 框架升级go get -u github.com/gogf/gf/v2 获取最新特性

提示:建议使用GF 2.4.4+版本,其对代码生成工具链做了显著优化

项目初始化后会生成如下关键目录:

├── internal
│   ├── dao       # 数据访问层(自动生成)
│   ├── model     # 数据结构层
│   ├── service   # 业务服务层
│   └── logic     # 业务逻辑实现
└── manifest
    └── config    # 配置文件目录

2. 数据库配置与DAO生成

2.1 数据库连接配置

config/config.yaml中配置MySQL连接信息:

database:
  default:
    link: "mysql:root:password@tcp(127.0.0.1:3306)/test_db"
    debug: true  # 开发环境建议开启SQL日志

对于多数据库实例场景,可以扩展配置:

database:
  user_db:
    link: "mysql:root:password@tcp(127.0.0.1:3306)/user_db"
  order_db:
    link: "mysql:root:password@tcp(127.0.0.1:3306)/order_db"

2.2 自动化DAO生成

在项目根目录创建hack/config.yaml配置生成规则:

gfcli:
  gen:
    dao:
      - link: "mysql:root:password@tcp(127.0.0.1:3306)/test_db"
        tables: "user,product"  # 指定需要生成的表
        descriptionTag: true    # 生成字段注释标签
        jsonCase: "CamelLower"  # JSON字段命名风格

执行生成命令:

gf gen dao

该命令会生成三层结构:

  • /internal/dao:数据操作对象(可扩展)
  • /internal/model/entity:数据表映射实体(禁止手动修改)
  • /internal/model/do:数据操作模型(工具维护)

典型DAO操作示例

// 查询单个用户
user, err := dao.User.Ctx(ctx).Where(do.User{Id: 1}).One()

// 事务操作
err := g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
    _, err := dao.User.Ctx(ctx).TX(tx).Insert(do.User{
        Name: "张三",
        Age:  25,
    })
    return err
})

3. 业务逻辑与Service生成

3.1 业务模型设计

internal/model目录下定义业务数据结构:

// 用户创建输入模型
type UserCreateInput struct {
    Name     string `v:"required"`  // 姓名
    Age      int    `v:"min:18"`    // 年龄校验
    Password string `pwd:"true"`    // 密码字段特殊处理
}

// 用户查询输出模型
type UserQueryOutput struct {
    Id       uint   `json:"id"`
    Name     string `json:"name"`
    Age      int    `json:"age"`
    CreateAt string `json:"createAt"`
}

3.2 Service接口生成

配置watchers.xml文件定义服务监听规则(可从官方示例获取基础模板),然后在internal/logic实现具体业务:

// logic/user/login.go
package user

import (
    "context"
    "demo/internal/model"
)

type sUser struct{}

func New() *sUser {
    return &sUser{}
}

func (s *sUser) Login(ctx context.Context, in model.UserLoginInput) (out *model.UserLoginOutput, err error) {
    // 业务逻辑实现
    if user, err := dao.User.Ctx(ctx).Where(do.User{
        Name:     in.Name,
        Password: encrypt(in.Password),
    }).One(); err != nil {
        return nil, err
    } else {
        out = &model.UserLoginOutput{
            Token: generateToken(user.Id),
        }
    }
    return
}

执行服务生成命令:

gf gen service

该命令会生成:

  • /internal/service 接口定义文件
  • /internal/logic/logic.go 接口注册文件

4. 接口暴露与API开发

4.1 Controller实现

internal/controller中编写接口处理器:

package controller

import (
    "context"
    "demo/internal/model"
    "demo/internal/service"
)

type cUser struct{}

var User = cUser{}

// SignUp 用户注册
func (c *cUser) SignUp(ctx context.Context, req *model.UserSignUpReq) (res *model.UserSignUpRes, err error) {
    err = service.User().Create(ctx, model.UserCreateInput{
        Name:     req.Name,
        Password: req.Password,
        Age:      req.Age,
    })
    return
}

4.2 API路由定义

api/v1目录定义OpenAPI规范:

package v1

import "github.com/gogf/gf/v2/frame/g"

type UserSignUpReq struct {
    g.Meta `path:"/user/sign-up" method:"post" tags:"用户服务" summary:"用户注册"`
    Name     string `v:"required|length:2,10"`  // 姓名校验
    Password string `v:"required|length:6,16"`  // 密码强度
    Age      int    `v:"min:18"`               // 年龄限制
}

type UserSignUpRes struct {
    Id uint `json:"id" dc:"用户ID"`
}

4.3 自动生成Swagger文档

Goframe会自动根据API定义生成文档:

gf swagger

访问 http://localhost:8000/swagger 即可查看交互式API文档。

5. 高级技巧与最佳实践

5.1 热更新配置

hack/watchers.xml中配置文件监听规则,实现数据库变更自动触发代码生成:

<watchers>
    <watch type="sql" link="mysql:root:password@tcp(127.0.0.1:3306)/test_db">
        <table name="user" genPath="./internal" />
    </watch>
</watchers>

启动监听服务:

gf watch

5.2 多模块代码生成

对于大型项目,可以通过分组配置实现模块化生成:

# hack/config.yaml
gfcli:
  gen:
    dao:
      - link: "mysql:root:password@tcp(127.0.0.1:3306)/user_db"
        path: "./internal/modules/user"
        tables: "user,user_profile"
      - link: "mysql:root:password@tcp(127.0.0.1:3306)/order_db"
        path: "./internal/modules/order"
        tables: "order,order_item"

5.3 自定义模板

hack/template目录下放置自定义模板文件,可覆盖默认生成逻辑:

hack/
└── template/
    ├── dao/       # DAO层模板
    ├── service/   # Service层模板
    └── model/     # 模型模板

例如修改DAO生成模板:

// hack/template/dao/dao.go.tpl
package {{.PackageName}}

import (
    "context"
    "github.com/gogf/gf/v2/frame/g"
)

type {{.ClassName}} struct {
    table string
}

func New{{.ClassName}}() *{{.ClassName}} {
    return &{{.ClassName}}{
        table: "{{.TableName}}",
    }
}
Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐