Go-Zero+mysql进行crud操作
-
- 目录
- 一、项目概述
-
- [1.1 项目背景](#1.1 项目背景)
- [1.2 项目目标](#1.2 项目目标)
- 二、整体流程图
- 三、环境准备
-
- [3.1 安装 Go](#3.1 安装 Go)
- [3.2 安装 go-zero 和 goctl](#3.2 安装 go-zero 和 goctl)
- [3.3 安装 MySQL](#3.3 安装 MySQL)
- 四、详细步骤
-
- [4.1 创建项目](#4.1 创建项目)
- [4.2 配置数据库连接](#4.2 配置数据库连接)
-
- [4.2.1 修改配置文件](#4.2.1 修改配置文件)
- [4.2.2 修改配置结构体](#4.2.2 修改配置结构体)
- [4.3 编写 API 文件](#4.3 编写 API 文件)
- [4.4 生成 API 代码](#4.4 生成 API 代码)
- [4.5 生成 Model 层](#4.5 生成 Model 层)
-
- [4.5.1 准备 SQL 文件](#4.5.1 准备 SQL 文件)
- [4.5.2 在数据库中执行 SQL](#4.5.2 在数据库中执行 SQL)
- [4.5.3 生成 Model 代码](#4.5.3 生成 Model 代码)
- [4.6 注册 Model 到服务上下文](#4.6 注册 Model 到服务上下文)
- [4.7 编写业务逻辑](#4.7 编写业务逻辑)
-
- [4.7.1 实现创建用户逻辑](#4.7.1 实现创建用户逻辑)
- [4.7.2 实现查询用户逻辑](#4.7.2 实现查询用户逻辑)
- [4.7.3 实现更新用户逻辑](#4.7.3 实现更新用户逻辑)
- [4.7.4 实现删除用户逻辑](#4.7.4 实现删除用户逻辑)
- [4.8 常见问题与解决](#4.8 常见问题与解决)
-
- [问题 1: field "name" is not set](#问题 1: field "name" is not set)
- [问题 2: sql: Scan error on column index X, name "created_at"](#问题 2: sql: Scan error on column index X, name "created_at")
- [问题 3: 连接数据库失败](#问题 3: 连接数据库失败)
- [4.9 测试验证](#4.9 测试验证)
-
- [4.9.1 启动服务](#4.9.1 启动服务)
- [4.9.2 测试创建用户](#4.9.2 测试创建用户)
- [4.9.3 测试查询用户](#4.9.3 测试查询用户)
- [4.9.4 测试更新用户](#4.9.4 测试更新用户)
- [4.9.5 测试删除用户](#4.9.5 测试删除用户)
- 五、项目结构说明
- 六、总结
-
- [6.1 开发流程回顾](#6.1 开发流程回顾)
- [6.2 关键命令速查](#6.2 关键命令速查)
本文详细介绍如何从零开始搭建一个基于 go-zero 框架的 RESTful API 项目,实现用户的增删改查功能。
关键词: Go-Zero, MySQL, RESTful API, 微服务, Go 语言, 数据库连接, CRUD 操作, goctl 工具
目录
- 一、项目概述
- 二、整体流程图
- 三、环境准备
- 四、详细步骤
- [4.1 创建项目](#4.1 创建项目)
- [4.2 配置数据库连接](#4.2 配置数据库连接)
- [4.3 编写 API 文件](#4.3 编写 API 文件)
- [4.4 生成 API 代码](#4.4 生成 API 代码)
- [4.5 生成 Model 层](#4.5 生成 Model 层)
- [4.6 注册 Model 到服务上下文](#4.6 注册 Model 到服务上下文)
- [4.7 编写业务逻辑](#4.7 编写业务逻辑)
- [4.8 常见问题与解决](#4.8 常见问题与解决)
- [4.9 测试验证](#4.9 测试验证)
- 五、项目结构说明
- 六、总结
一、项目概述
1.1 项目背景
go-zero 是一个集成了各种工程实践的 Web 和 RPC 框架,具有以下特点:
- 简单易用:通过 goctl 工具一键生成代码
- 微服务架构:原生支持微服务设计
- 高性能:内置限流、熔断、负载均衡等功能
- 代码规范:统一的代码结构和风格
1.2 项目目标
实现一个用户管理 RESTful API,包含以下接口:
| 方法 | 路径 | 功能 |
|---|---|---|
| POST | /api/users | 创建用户 |
| GET | /api/users | 查询用户 |
| PUT | /api/users | 更新用户 |
| DELETE | /api/users | 删除用户 |
二、整体流程图

三、环境准备
3.1 安装 Go
确保已安装 Go 1.19+:
bash
go version
3.2 安装 go-zero 和 goctl
bash
# 安装 go-zero 框架
go install github.com/zeromicro/go-zero/latest@latest
# 安装 goctl 代码生成工具
go install github.com/zeromicro/go-zero/tools/goctl@latest
# 验证安装
goctl --version
3.3 安装 MySQL
确保 MySQL 服务正常运行,并创建好数据库:
sql
CREATE DATABASE test_demo DEFAULT CHARACTER SET utf8mb4;
四、详细步骤
4.1 创建项目
使用 goctl 创建新的 API 项目:
bash
# 创建项目
goctl api new mysqldemo
# 进入项目目录
cd mysqldemo
生成的初始项目结构:
mysqldemo/
├── etc/
│ └── user-api.yaml # 配置文件
├── internal/
│ ├── config/ # 配置结构体
│ ├── handler/ # HTTP 处理器
│ ├── logic/ # 业务逻辑
│ ├── model/ # 数据模型(初始为空)
│ ├── svc/ # 服务上下文
│ └── types/ # 类型定义
├── user.api # API 定义文件
└── user.go # 入口文件
4.2 配置数据库连接
4.2.1 修改配置文件
编辑 etc/user-api.yaml,添加 MySQL 数据源配置:
yaml
Name: mysqldemo-api
Host: 0.0.0.0
Port: 8888
Mysql:
DataSource: root:your_password@tcp(127.0.0.1:3306)/test_demo?charset=utf8mb4&parseTime=true
重要提示:
必须添加 parseTime=true 参数,否则时间字段会报错:
❌ 错误: parseTime-true (使用了横线)
✅ 正确: parseTime=true (使用等号)
4.2.2 修改配置结构体
编辑 internal/config/config.go,添加 MySQL 配置字段:
go
package config
import "github.com/zeromicro/go-zero/rest"
type Config struct {
rest.RestConf
Mysql struct {
DataSource string
}
}
4.3 编写 API 文件
编辑 user.api 文件,定义 API 接口:
go
// user.api
type (
// 用户实体
User {
Id int64 `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
Email string `json:"email"`
CreatedAt string `json:"createdAt,optional"`
UpdatedAt string `json:"updatedAt,optional"`
}
// 创建用户请求
UserCreateReq {
Name string `json:"name"` // 必填字段
Age int `json:"age,optional"` // 可选字段
Email string `json:"email"` // 必填字段
}
// 更新用户请求
UserUpdateReq {
Id int64 `json:"id"`
Name string `json:"name,optional"`
Age int `json:"age,optional"`
Email string `json:"email,optional"`
}
// 查询用户请求
UserQueryReq {
Id int64 `form:"id,optional"`
Email string `form:"email,optional"`
}
// 统一响应结构
Response {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data,optional"`
}
)
service user-api {
@handler createUser
post /api/users (UserCreateReq) returns (Response)
@handler getUser
get /api/users (UserQueryReq) returns (Response)
@handler updateUser
put /api/users (UserUpdateReq) returns (Response)
@handler deleteUser
delete /api/users (UserQueryReq) returns (Response)
}
注意事项:
json:"name"- 必填字段,不带optionaljson:"age,optional"- 可选字段,带optional标签form:"id"- GET/DELETE 请求使用form标签json:"id"- POST/PUT 请求使用json标签
4.4 生成 API 代码
根据 API 文件生成代码:
bash
goctl api go -api user.api -dir .
生成内容说明:
| 目录 | 说明 |
|---|---|
internal/handler/ |
HTTP 处理器,负责解析请求和返回响应 |
internal/logic/ |
业务逻辑层,实现具体功能(框架已生成,需填充逻辑) |
internal/types/ |
请求/响应类型定义 |
internal/config/ |
配置结构体(已在步骤 4.2 修改) |
internal/svc/ |
服务上下文(需在步骤 4.6 修改) |
4.5 生成 Model 层
4.5.1 准备 SQL 文件
在 sql/user.sql 中定义表结构:
sql
CREATE TABLE `user` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL COMMENT '用户姓名',
`age` int DEFAULT NULL COMMENT '用户年龄',
`email` varchar(255) DEFAULT NULL COMMENT '用户邮箱',
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
4.5.2 在数据库中执行 SQL
bash
mysql -u root -p test_demo < sql/user.sql
4.5.3 生成 Model 代码
使用 goctl 从 SQL 文件生成 Model:
bash
goctl model mysql ddl -src sql/user.sql -dir internal/model -c=false
参数说明:
-src sql/user.sql:指定 SQL 文件路径-dir internal/model:指定 Model 输出目录-c=false:不生成缓存代码(简单场景可关闭)
生成的 Model 文件:
internal/model/
├── usermodel.go # 自定义扩展方法(可编辑)
├── usermodel_gen.go # 自动生成的基础方法(勿修改)
└── vars.go # 错误变量定义
usermodel_gen.go 自动生成的接口:
go
type userModel interface {
Insert(ctx context.Context, data *User) (sql.Result, error)
FindOne(ctx context.Context, id int64) (*User, error)
FindOneByEmail(ctx context.Context, email string) (*User, error)
Update(ctx context.Context, data *User) error
Delete(ctx context.Context, id int64) error
}
4.6 注册 Model 到服务上下文
编辑 internal/svc/servicecontext.go,初始化数据库连接和 UserModel:
go
package svc
import (
"mysqldemo/internal/config"
"mysqldemo/internal/model"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
type ServiceContext struct {
Config config.Config
UserModel model.UserModel
}
func NewServiceContext(c config.Config) *ServiceContext {
// 创建数据库连接
conn := sqlx.NewMysql(c.Mysql.DataSource)
return &ServiceContext{
Config: c,
UserModel: model.NewUserModel(conn),
}
}
4.7 编写业务逻辑
4.7.1 实现创建用户逻辑
编辑 internal/logic/createuserlogic.go:
go
package logic
import (
"context"
"mysqldemo/internal/model"
"mysqldemo/internal/svc"
"mysqldemo/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type CreateUserLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewCreateUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateUserLogic {
return &CreateUserLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *CreateUserLogic) CreateUser(req *types.UserCreateReq) (*types.Response, error) {
// 构建用户对象
user := &model.User{
Name: req.Name,
Age: req.Age,
Email: req.Email,
}
// 调用 Model 层插入数据
res, err := l.svcCtx.UserModel.Insert(l.ctx, user)
if err != nil {
return nil, err
}
// 获取自增 ID
id, err := res.LastInsertId()
if err != nil {
return nil, err
}
return &types.Response{
Code: 200,
Message: "success",
Data: map[string]interface{}{"id": id},
}, nil
}
4.7.2 实现查询用户逻辑
编辑 internal/logic/getuserlogic.go:
go
package logic
import (
"context"
"mysqldemo/internal/model"
"mysqldemo/internal/svc"
"mysqldemo/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetUserLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserLogic {
return &GetUserLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetUserLogic) GetUser(req *types.UserQueryReq) (*types.Response, error) {
var user *model.User
var err error
// 支持按 ID 或 Email 查询
if req.Id > 0 {
user, err = l.svcCtx.UserModel.FindOne(l.ctx, req.Id)
} else if req.Email != "" {
user, err = l.svcCtx.UserModel.FindOneByEmail(l.ctx, req.Email)
} else {
return &types.Response{
Code: 400,
Message: "参数错误,请提供 id 或 email",
}, nil
}
if err != nil {
if err == model.ErrNotFound {
return &types.Response{
Code: 404,
Message: "用户不存在",
}, nil
}
return nil, err
}
return &types.Response{
Code: 200,
Message: "success",
Data: user,
}, nil
}
4.7.3 实现更新用户逻辑
编辑 internal/logic/updateuserlogic.go:
go
package logic
import (
"context"
"mysqldemo/internal/model"
"mysqldemo/internal/svc"
"mysqldemo/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type UpdateUserLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewUpdateUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateUserLogic {
return &UpdateUserLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *UpdateUserLogic) UpdateUser(req *types.UserUpdateReq) (*types.Response, error) {
// 先查询用户是否存在
user, err := l.svcCtx.UserModel.FindOne(l.ctx, req.Id)
if err != nil {
if err == model.ErrNotFound {
return &types.Response{
Code: 404,
Message: "用户不存在",
}, nil
}
return nil, err
}
// 更新字段(只更新非空字段)
if req.Name != "" {
user.Name = req.Name
}
if req.Age > 0 {
user.Age = req.Age
}
if req.Email != "" {
user.Email = req.Email
}
// 执行更新
err = l.svcCtx.UserModel.Update(l.ctx, user)
if err != nil {
return nil, err
}
return &types.Response{
Code: 200,
Message: "更新成功",
Data: user,
}, nil
}
4.7.4 实现删除用户逻辑
编辑 internal/logic/deleteuserlogic.go:
go
package logic
import (
"context"
"mysqldemo/internal/svc"
"mysqldemo/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type DeleteUserLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewDeleteUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteUserLogic {
return &DeleteUserLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *DeleteUserLogic) DeleteUser(req *types.UserQueryReq) (*types.Response, error) {
// 删除用户
err := l.svcCtx.UserModel.Delete(l.ctx, req.Id)
if err != nil {
return nil, err
}
return &types.Response{
Code: 200,
Message: "删除成功",
}, nil
}
4.8 常见问题与解决
问题 1: field "name" is not set
原因 :请求没有正确设置 Content-Type: application/json
解决:确保 curl 命令包含请求头:
bash
curl -X POST http://127.0.0.1:8888/api/users \
-H "Content-Type: application/json" \
-d '{"name":"张三","age":25,"email":"zhangsan@example.com"}'
问题 2: sql: Scan error on column index X, name "created_at"
原因 :数据库连接字符串缺少 parseTime=true 参数
解决 :修改 etc/user-api.yaml:
yaml
# 错误 ❌
DataSource: root:password@tcp(127.0.0.1:3306)/test_demo?charset=utf8mb4&parseTime-true
# 正确 ✅
DataSource: root:password@tcp(127.0.0.1:3306)/test_demo?charset=utf8mb4&parseTime=true
问题 3: 连接数据库失败
排查步骤:
- 检查 MySQL 服务是否启动
- 检查用户名、密码是否正确
- 检查数据库是否存在
- 检查网络连接和防火墙设置
4.9 测试验证
4.9.1 启动服务
bash
go run user.go -f etc/user-api.yaml
输出:
Starting server at 0.0.0.0:8888...
4.9.2 测试创建用户
bash
curl -X POST http://127.0.0.1:8888/api/users \
-H "Content-Type: application/json" \
-d '{"name":"刘德华","age":35,"email":"dehua@163.com"}'
响应:
json
{
"code": 200,
"message": "success",
"data": {"id": 1}
}
4.9.3 测试查询用户
按 ID 查询:
bash
curl "http://127.0.0.1:8888/api/users?id=1"
响应:
json
{
"code": 200,
"message": "success",
"data": {
"id": 1,
"name": "刘德华",
"age": 35,
"email": "dehua@163.com",
"createdAt": "2025-07-19T07:00:00Z",
"updatedAt": "2025-07-19T07:00:00Z"
}
}
按 Email 查询:
bash
curl "http://127.0.0.1:8888/api/users?email=dehua@163.com"
4.9.4 测试更新用户
bash
curl -X PUT http://127.0.0.1:8888/api/users \
-H "Content-Type: application/json" \
-d '{"id":1,"name":"刘德虎","age":36}'
响应:
json
{
"code": 200,
"message": "更新成功",
"data": {
"id": 1,
"name": "刘德虎",
"age": 36,
"email": "dehua@163.com"
}
}
4.9.5 测试删除用户
bash
curl -X DELETE "http://127.0.0.1:8888/api/users?id=1"
响应:
json
{
"code": 200,
"message": "删除成功"
}
五、项目结构说明
mysqldemo/
├── etc/
│ └── user-api.yaml # 配置文件
├── internal/
│ ├── config/
│ │ └── config.go # 配置结构体
│ ├── handler/
│ │ ├── routes.go # 路由注册
│ │ ├── createuserhandler.go
│ │ ├── getuserhandler.go
│ │ ├── updateuserhandler.go
│ │ └── deleteuserhandler.go
│ ├── logic/
│ │ ├── createuserlogic.go # 创建用户逻辑 ⭐
│ │ ├── getuserlogic.go # 查询用户逻辑 ⭐
│ │ ├── updateuserlogic.go # 更新用户逻辑 ⭐
│ │ └── deleteuserlogic.go # 删除用户逻辑 ⭐
│ ├── model/
│ │ ├── usermodel.go # Model 扩展(可编辑)
│ │ ├── usermodel_gen.go # Model 基础(自动生成)
│ │ └── vars.go # 错误定义
│ ├── svc/
│ │ └── servicecontext.go # 服务上下文
│ └── types/
│ └── types.go # 类型定义
├── sql/
│ └── user.sql # 数据库建表语句
├── user.api # API 定义文件 ⭐
├── user.go # 入口文件
├── go.mod
└── go.sum
核心文件说明:
| 文件 | 作用 | 编辑建议 |
|---|---|---|
etc/user-api.yaml |
配置文件 | 修改数据库连接等配置 |
internal/config/config.go |
配置结构体 | 添加 MySQL 配置字段 |
user.api |
定义 API 接口 | 根据需求编写,修改后重新生成代码 |
internal/logic/*.go |
业务逻辑 | 重点编写,实现核心功能 |
internal/model/usermodel.go |
Model 扩展 | 可添加自定义查询方法 |
internal/model/usermodel_gen.go |
Model 基础 | 勿修改,重新生成会覆盖 |
internal/svc/servicecontext.go |
服务上下文 | 注册 Model 依赖 |
六、总结
6.1 开发流程回顾
创建项目 → 配置数据库 → 编写 API 文件 → 生成 API 代码
→ 生成 Model → 注册服务上下文 → 编写逻辑 → 测试验证
6.2 关键命令速查
| 步骤 | 命令 |
|---|---|
| 创建项目 | goctl api new mysqldemo |
| 生成 API 代码 | goctl api go -api user.api -dir . |
| 生成 Model | goctl model mysql ddl -src sql/user.sql -dir internal/model -c=false |
| 启动服务 | go run user.go -f etc/user-api.yaml |