Go框架 Gorm、Kitex| 青训营笔记

155 阅读3分钟

这是我参与【第五届青训营】伴学笔记创作活动的第7天

主要内容:

1、Gorm

Gorm是一个已经选代了10年+的功能虽大的 ORM 框架,在字节内部被广泛使用并且拥有非常丰富的开源扩展。

由于前几天已经学习过了gorm的基本语句使用,这里就不多赘述了

软删除

在结构体加一个字段 Deleted gorm.DeleteAt

删除单条操作:

u := User{ID:111}
db.Delete(&u)

批量删除:

db.Where("age=?",20).Delete(&User{})
users:=make(*[]User, 0)

在查询时会忽略被软删除的记录:

db.Where("age = 20").Find(&Users)

在查询时不会忽略被软删除的记录:

db.Unscoped().Where("age=20").Find(&Users)

GORM事务

1、Gorm 提供了 Begin、Commit、 Rollback 方法用于使用事务

db,err ;= gorm.Open(mysgl.Open("username:passwordatcp(localhost:9910)/database?charser=utf8"),
    &gorm.Config{})
if err != nil {
    panic( v:"failed to connect database")
}
tx := db.Begin() // 开始事务
//在事务中执行一些 db 操作 (从这里开始,您应该使用tx  而不是db)
if err = tx.Create(&User(Name: "name"}).Error; err != nil {tx.Rollback()
//遇到错误时回滚事务
return
if err = tx.Create(&User(Name: "name1"}).Error; err != nil {
    tx.Rollback()
    // 遇到错误时回滚事务
    return
}
// 提交事务
tx.Commit()

2、Gorm 提供了 Tansaction 方法用于自动提交事务避免用户漏写 Commit、 Rollback

db,err := gorm,0pen(mysgl.0pen("username:password@tcp(localhost:9910)/database?charset=utf8"),
    &gorm.Config{})
if err != nil {
    panic("failed to connect database")
}
if err = db.Transaction(func(tx *gorm.DB) error {
    if err = tx.Create(&User{Name: "name"}).Error; err != nil {
        return err
    }
    if err = tx.Create(&User{Name: "name1"}).Error; err != nil {
        tx.Rollback()
        return err
    }
    return nil
});err != nil{
    return
}

3、Hook 是在创建、查询、更新、删除等操作之前、之后自动调用的函数,如果任何 Hook 返回错误GORM 将停止后续的操作并回滚事务

type User struct {
    ID    int64
    Name  string  `gorm:"default:galeone"`
    Age    int64  `gorm:"default:18"`
}
type Email struct {
    ID   int64
    Name string
    Email string
}
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
    if u.Age <0{
        return errors.New( text: "can't save invalid data")
    }
    return
}

func (u *User) AfterCreate(tx *gorm.DB) (err error) {
    return tx.Create(&Email{ID: u.ID. Email: u.Name +"@***.com"}).Error
}

4、对于写操作(创建、更新、删除),为了确保数据的完整性,GORM 会将它们封装在事务内运行但这会降低性能,你可以使用 SkipDefaultTransaction 关闭默认事务

db,err := gorm.Open(mysql.0pen("username:password@tcp(localhost:9910)/database?charset=utf8"),
    &gorm.Config{
        SkipDefaultTransaction: true// 关闭默认事务
        PrepareStmt:            true},// 缓存预编译语句
}
if err != nil {
    panic("failed to connect database")
}

5、gorm扩展生态

扩展生态链接
GORM代码生成工具github.com/go-gorm/gen
GORM 分片库方案github.com/go-gorm/sha…
GORM 手动索引github.com/go-gorm/hin…
GORM 乐观锁github.com/go-gorm/opt…
GORM 读写分离github.com/go-gorm/dbr…
GORM OpenTelemetry 扩展github.com/go-gorm/ope…

2、Kitex

Kitex是字节内部的 Golang 微眼务 RPC 框架,具有高性能、强可扩展的主要特点,支持多协议并且拥有丰富的开源扩展。

注意:Kitex目前对Windows的支持不完善,如果本地开发环境是Windows的同学建议使用虚拟机或WSL2

安装代码生成工具

go install github.com/cloudwego/kitex/tool/cmd/kitext@latest

go install github.com/cloudwego/thriftgo@latest

生成代码

生成代码命令:Kitex -module example -service example echo.thrift

image.png

基本使用

服务器默认监听8888端口

package main
import(
    "context"
    "example/kitex_gen/api"
)

// EchoImpl implements the last service interface defined in the IDL
type EchoImpl struct{}

// Echo implements the EchoImpl interface
func (s *EchoImpl) Echo(ctx context.(ontext,reg *api.Reauest) (resp *api.Response, err error) {
    // TODO: Your code here ...
}

Client 发起请求

创建Client

import. "examplerkitex_gen/api/echo"
import "github.com/cloudnego/kitex/client"
...
c,err := echo.NewClient("example", client.WithHostPorts("0.0.0.0:8888"))

if err != nil {
    log.Fatal(err)
}

发起请求

import "example.kitex_gen/api"
...
reg := &api.Request{Message: "my request"}
resp,err := c.Echo(context.Background(), req, callopt.WithRPCTimeout(3*time.Second))
if err != nil {
    log.Fatal(err)
}
log.Println(resp)

Kitex生态

扩展生态链接
XDS 扩展github.com/kitex-contr…
opentelemetry 护展https!//github.com/kitex-contrib/obs-opentelemetry
ETCD 服务注册与发现扩展github.com/kitex-contr…
Nacos 服务注册与发现扩展github.com/kitex-contr…
Zookeeper 服务注册与发现扩展github.com/kitex-contr…
polaris 扩展github.com/kitex-contr…
丰富的示例代码与业务Demogithub.com/cloudwego/k…

课程链接

live.juejin.cn/4354/989924…