go-zero微服務(wù)《案例一:mysql的CURD操作》

使用goctl自動(dòng)生成api數(shù)據(jù)模型的代碼

  • 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; 入?yún)ⅲ╩obile:手機(jī)號,passwd:密碼,code:圖片驗(yàn)證碼)
// 2. 用戶登錄/open/authorization;  入?yún)ⅲ╩obile:手機(jī)號,passwd:密碼,code:圖片驗(yàn)證碼)
// 3. 圖片驗(yàn)證碼請求/open/verify; ticket:圖片驗(yàn)證碼的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"`
    }
    //圖片驗(yàn)證碼支持
    VerifyReq struct {
        ticket string `json:"ticket"`
    }
    //圖片驗(yàn)證碼支持
    VerifyResp struct {
        data string `json:"data"`
    }
)

// 一個(gè)文件里面只能有一個(gè) service
service open-api {
    @doc(
        summary: 公開的api函數(shù)
        desc: >
        register: 用戶注冊,
        authorization: 用戶登錄,
        verify: 圖片驗(yàn)證碼接口
    )
    @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 {
    //啟動(dòng)Gorm支持
    db, err := gorm.Open(mysql.Open(c.DataSourceName), &gorm.Config{
        NamingStrategy: schema.NamingStrategy{
            TablePrefix:   "tech_", // 表名前綴,`User` 的表名應(yīng)該是 `t_users`
            SingularTable: true,    // 使用單數(shù)表名,啟用該選項(xiàng),此時(shí),`User` 的表名應(yīng)該是 `t_user`
        },
    })
    //如果出錯(cuò)就GameOver了
    if err != nil {
        panic(err)
    }
    //自動(dòng)同步更新表結(jié)構(gòu),不要建表了O(∩_∩)O哈哈~
    db.AutoMigrate(&models.User{})

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

  • 新建數(shù)據(jù)庫的 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)"`
}
//在創(chuàng)建前檢驗(yàn)驗(yàn)證一下密碼的有效性
func (u *User) BeforeCreate(db *gorm.DB) error {
    if len(u.Passwd) < 6 {
        return errors.New("密碼太簡單了")
    }
    //對密碼進(jìn)行加密存儲
    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) // 保存在數(shù)據(jù)庫的密碼,雖然每次生成都不同,只需保存一份即可
    return encodePWD
}
//密碼校驗(yàn)
func CheckPassword(plainpwd, cryptedpwd string) bool {
    err := bcrypt.CompareHashAndPassword([]byte(cryptedpwd), []byte(plainpwd)) //驗(yàn)證(對比)
    return err == nil
}

  • 修改實(shí)現(xiàn)業(yè)務(wù)邏輯 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
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容