【CloudWeGo】字节跳动 Golang 微服务框架 Hertz 集成 Gorm 实战

hello,大家好,我是千羽。
上一篇,讲了《字节跳动 Golang 微服务 HTTP 框架 Hertz》入门,今天我们就通过一个实战项目,来体验 Hertz 和 Gorm 的集成。
在 Golang 开发中,许多框架和功能不像 Java 那么成熟,需要开发者自己实现。而字节跳动开源的 Hertz 框架,则提供了丰富的功能,堪称 Golang 版的 Spring Boot。
Step 1:Fork Hertz 官方 Demo
首先,将官方的 Hertz 示例仓库 fork 到自己的 GitHub 仓库,方便后续操作:

然后,将项目 clone 到本地,按照官方文档操作。

具体仓库地址:https://github.com/cloudwego/hertz-examples/tree/main/bizdemo/hertz_gorm
Step 2:配置与启动项目
官方 Readme 提供了启动指导,根据文档说明进行以下步骤:
使用 Docker 启动 MySQL 容器:
cd bizdemo/hertz_gorm && docker-compose up

连接 MySQL 确保数据库正常运行:

编译并启动项目:
cd bizdemo/hertz_gorm
go build -o hertz_gorm && ./hertz_gorm
若启动成功,你将看到以下日志输出:
HERTZ: HTTP server listening on address=[::]:8888
Step 3:接口调试
在项目启动后,我们可以逐一测试接口。Hertz 项目包含了一些基本的 CRUD 接口,方便我们进行数据的操作和验证。
根据启动的日志,我们进行各个接口验证
absolutePath=/v1/user/create/
absolutePath=/v1/user/delete/:user_id
absolutePath=/v1/user/query/
absolutePath=/v1/user/update/:user_id
absolutePath=/ping

  1. /ping 接口测试
    请求 URL: http://localhost:8888/ping
    响应示例:
    {
    “message”: “pong”
    }
  2. 创建用户接口 /v1/user/create/
    请求 URL: http://localhost:8888/v1/user/create/
    请求参数:
    {
    “name”: “千羽”,
    “gender”: 1,
    “age”: 18,
    “introduce”: “程序员”
    }
    响应示例:
    {
    “code”: 1,
    “msg”: “”
    }

MySQL 查询效果:

  1. 查询用户接口 /v1/user/query/
    请求 URL: http://localhost:8888/v1/user/query/
    请求参数:
    {
    “page”: 1,
    “page_size”:10,
    “keyword”:”千羽”
    }
    响应示例:
    {
    “code”: 1,
    “msg”: “”,
    “users”: [
    {
    “user_id”: 1,
    “name”: “千羽”,
    “gender”: 1,
    “age”: 18,
    “introduce”: “程序员”
    }
    ],
    “total”: 1
    }
  2. 删除用户接口 /v1/user/delete/1
    删除,软删除,不会真正的删除
    Step 4:代码解析
    创建用户的逻辑 /v1/user/create/
    Service 层:
    // CreateUser .
    // @router /v1/user/create/ [POST]
    func CreateUser(ctx context.Context, c app.RequestContext) { var err error var req user_gorm.CreateUserRequest err = c.BindAndValidate(&req) if err != nil { c.JSON(consts.StatusBadRequest, &user_gorm.CreateUserResponse{Code: user_gorm.Code_ParamInvalid, Msg: err.Error()}) return } if err = mysql.CreateUser([]model.User{
    {
    Name: req.Name,
    Gender: int64(req.Gender),
    Age: req.Age,
    Introduce: req.Introduce,
    },
    }); err != nil {
    c.JSON(consts.StatusInternalServerError, &user_gorm.CreateUserResponse{Code: user_gorm.Code_DBErr, Msg: err.Error()})
    return
    } resp := new(user_gorm.CreateUserResponse)
    resp.Code = user_gorm.Code_Success
    c.JSON(consts.StatusOK, resp)
    }
    MySQL 层:
    func CreateUser(users []*model.User) error {
    return DB.Create(users).Error
    }
    查询用户的逻辑 /v1/user/query/
    Service 层:
    // QueryUser .
    // @router /v1/user/query/ [POST]
    func QueryUser(ctx context.Context, c *app.RequestContext) {
    var err error
    var req user_gorm.QueryUserRequest
    err = c.BindAndValidate(&req)
    if err != nil {
    c.JSON(consts.StatusBadRequest, &user_gorm.QueryUserResponse{Code: user_gorm.Code_ParamInvalid, Msg: err.Error()})
    return
    } users, total, err := mysql.QueryUser(req.Keyword, req.Page, req.PageSize)
    if err != nil {
    c.JSON(consts.StatusInternalServerError, &user_gorm.QueryUserResponse{Code: user_gorm.Code_DBErr, Msg: err.Error()})
    return
    }
    c.JSON(consts.StatusOK, &user_gorm.QueryUserResponse{Code: user_gorm.Code_Success, Users: pack.Users(users), Totoal: total})
    }
    MySQL 层:
    func QueryUser(keyword string, page, pageSize int64) ([]model.User, int64, error) {
    db := DB.Model(model.User{})
    if keyword != nil && len(keyword) != 0 { db = db.Where(DB.Or(“name like ?”, “%”+keyword+”%”).
    Or(“introduce like ?”, “%”+keyword+”%”)) } var total int64 if err := db.Count(&total).Error; err != nil { return nil, 0, err } var res []model.User
    if err := db.Limit(int(pageSize)).Offset(int(pageSize * (page – 1))).Find(&res).Error; err != nil {
    return nil, 0, err
    }
    return res, total, nil
    }
    更新用户的逻辑 /v1/user/update/1
    Service 层:
    // UpdateUser .
    // @router /v1/user/update/:user_id [POST]
    func UpdateUser(ctx context.Context, c *app.RequestContext) {
    var err error
    var req user_gorm.UpdateUserRequest
    err = c.BindAndValidate(&req)
    if err != nil {
    c.JSON(consts.StatusBadRequest, &user_gorm.UpdateUserResponse{Code: user_gorm.Code_ParamInvalid, Msg: err.Error()})
    return
    } u := &model.User{}
    u.ID = uint(req.UserID)
    u.Name = req.Name
    u.Gender = int64(req.Gender)
    u.Age = req.Age
    u.Introduce = req.Introduce if err = mysql.UpdateUser(u); err != nil {
    c.JSON(consts.StatusInternalServerError, &user_gorm.UpdateUserResponse{Code: user_gorm.Code_DBErr, Msg: err.Error()})
    return
    } c.JSON(consts.StatusOK, &user_gorm.UpdateUserResponse{Code: user_gorm.Code_Success})
    }
    mysql 层
    func UpdateUser(user *model.User) error {
    return DB.Updates(user).Error
    }
    删除 /v1/user/delete/:user_id
    删除,软删除,不会真正的删除
    Service 层:
    // DeleteUser .
    // @router /v1/user/delete/:user_id [POST]
    func DeleteUser(ctx context.Context, c *app.RequestContext) {
    var err error
    var req user_gorm.DeleteUserRequest
    err = c.BindAndValidate(&req)
    if err != nil {
    c.JSON(consts.StatusBadRequest, &user_gorm.DeleteUserResponse{Code: user_gorm.Code_ParamInvalid, Msg: err.Error()})
    return
    }
    if err = mysql.DeleteUser(req.UserID); err != nil {
    c.JSON(consts.StatusInternalServerError, &user_gorm.DeleteUserResponse{Code: user_gorm.Code_DBErr, Msg: err.Error()})
    return
    } c.JSON(consts.StatusOK, &user_gorm.DeleteUserResponse{Code: user_gorm.Code_Success})
    }
    mysql 层

func DeleteUser(userId int64) error {
return DB.Where(“id = ?”, userId).Delete(&model.User{}).Error
}

总结
通过这个项目,我们体验了 Hertz 集成 Gorm 的基本操作,涵盖了用户的创建、查询、更新和删除接口。在 Golang 生态中,虽然框架没有 Java 完善,但 Hertz 带来了简便的解决方案,有助于开发者快速上手。
参考文章:https://www.cloudwego.io/zh/docs/hertz/

声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/423591.html

联系我们
联系我们
分享本页
返回顶部