这是我参与【第五届青训营】伴学笔记创作活动的第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
基本使用
服务器默认监听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… |
| 丰富的示例代码与业务Demo | github.com/cloudwego/k… |