go-zero微服务《案例一:mysql的CURD操作》

使用goctl自动生成api数据模型的代码

  • goctl安装
#  for Go 1.15 and earlier
go get -u github.com/zeromicro/go-zero/tools/goctl@latest
go install github.com/zeromicro/go-zero/tools/goctl@latest

# for Go 1.16 and later
go install github.com/zeromicro/go-zero/tools/goctl@latest
  • 定义xxx.api文档

// 1. 用户注册/open/register; 入参(mobile:手机号,passwd:密码,code:图片验证码)
// 2. 用户登录/open/authorization;  入参(mobile:手机号,passwd:密码,code:图片验证码)
// 3. 图片验证码请求/open/verify; ticket:图片验证码的id; data:base64格式的图片
type (
    UserOptReq struct {
        mobile string `json:"mobile"`
        passwd string `json:"passwd"`
        code   string `json:"code"`
    }

    UserOptResp struct {
        id    uint   `json:"id"`
        token string `json:"token"`
    }
    //图片验证码支持
    VerifyReq struct {
        ticket string `json:"ticket"`
    }
    //图片验证码支持
    VerifyResp struct {
        data string `json:"data"`
    }
)

// 一个文件里面只能有一个 service
service open-api {
    @doc(
        summary: 公开的api函数
        desc: >
        register: 用户注册,
        authorization: 用户登录,
        verify: 图片验证码接口
    )
    @server(
        handler: registerHandler
        folder: open
    )
    post /open/register(UserOptReq) returns(UserOptResp)
    
    
    @server(
        handler: authorizationHandler
        folder: open
    )
    post /open/authorization(UserOptReq) returns(UserOptResp)

    @server(
        handler: verifyHandler
        folder: open
    )
    post /open/verify(VerifyReq) returns(VerifyResp)
    
}
  • 生成代码
goctl api go -api xxx.api -dir .
# 使用goctl生成api代码,生成go语言代码,api的定义模版本是xxx.api, -dir指定生成的代码路径

集成Gorm操作mysql

  • 修改配置文件 etc/xxx-api.yaml
Name: open-api
Host: 0.0.0.0
Port: 8888
DataSourceName: root:<passwd>@(127.0.0.1:3306)/<database_name>?charset=utf8
  • 在internal/config/config.go中添加DataSourceName
type Config struct {
    rest.RestConf
    DataSourceName string
}
  • 修改svc/servicecontext.go
package svc

import (
    "hello/internal/config"
    "hello/internal/models"

    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "gorm.io/gorm/schema"
)

type ServiceContext struct {
    Config  config.Config
    DbEngin *gorm.DB
}

func NewServiceContext(c config.Config) *ServiceContext {
    //启动Gorm支持
    db, err := gorm.Open(mysql.Open(c.DataSourceName), &gorm.Config{
        NamingStrategy: schema.NamingStrategy{
            TablePrefix:   "tech_", // 表名前缀,`User` 的表名应该是 `t_users`
            SingularTable: true,    // 使用单数表名,启用该选项,此时,`User` 的表名应该是 `t_user`
        },
    })
    //如果出错就GameOver了
    if err != nil {
        panic(err)
    }
    //自动同步更新表结构,不要建表了O(∩_∩)O哈哈~
    db.AutoMigrate(&models.User{})

    return &ServiceContext{Config: c, DbEngin: db}
}

  • 新建数据库的 models\models.go
//models\models.go文件
package models

import (
    "errors"
    "hello/internal/utils"

    "gorm.io/gorm"
)

type User struct {
    gorm.Model
    Mobile string `gorm:"index:mobile;type:varchar(13)"`
    Passwd string `gorm:"type:varchar(64)"`
}
//在创建前检验验证一下密码的有效性
func (u *User) BeforeCreate(db *gorm.DB) error {
    if len(u.Passwd) < 6 {
        return errors.New("密码太简单了")
    }
    //对密码进行加密存储
    u.Passwd = utils.Password(u.Passwd)
    return nil
}
  • 新建utils utils.Password工具包
package utils

import (
    "fmt"

    "golang.org/x/crypto/bcrypt"
)

//密码加密
func Password(plainpwd string) string {
    //谷歌的加密包
    hash, err := bcrypt.GenerateFromPassword([]byte(plainpwd), bcrypt.DefaultCost) //加密处理
    if err != nil {
        fmt.Println(err)
    }
    encodePWD := string(hash) // 保存在数据库的密码,虽然每次生成都不同,只需保存一份即可
    return encodePWD
}
//密码校验
func CheckPassword(plainpwd, cryptedpwd string) bool {
    err := bcrypt.CompareHashAndPassword([]byte(cryptedpwd), []byte(plainpwd)) //验证(对比)
    return err == nil
}

  • 修改实现业务逻辑 logic\xxx\registerlogic.go
package logic

import (
    "context"

    "hello/internal/models"
    "hello/internal/svc"
    "hello/internal/types"

    "github.com/tal-tech/go-zero/core/logx"
)

type RegisterLogic struct {
    ctx context.Context
    logx.Logger
    svcCtx *svc.ServiceContext
}

func NewRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext) RegisterLogic {
    return RegisterLogic{
        ctx:    ctx,
        Logger: logx.WithContext(ctx),
        svcCtx: svcCtx,
    }
}

func (l *RegisterLogic) Register(req types.UserOptReq) (*types.UserOptResp, error) {
    user := models.User{
        Mobile: req.Mobile,
        Passwd: req.Passwd,
    }
    result := l.svcCtx.DbEngin.Create(&user)
    return &types.UserOptResp{
        Id: user.ID,
    }, result.Error
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351

推荐阅读更多精彩内容