golang-go-zero-教程-Model
本系列为作者跟着Mikaelemmmm的b站教学视频学习时做的笔记
指令
通过sql或表生成model
|
|
Mikaelemmmm推荐使用navcat先生成表再通过表生成sql和model
这里我构建好了sql之后使用,注意这里没有cache所以没有-c选项:
|
|
Model文件
生成的文件放到任意位置
引入Model分4步:
- 修改yaml
|
|
- 修改config.go,给Config结构体添加相应字段
|
|
- 添加中间件客户端到svcCtx结构体字段
|
|
- 给svcCtx的New函数添加相应的字段值
|
|
之后就可以在handler和logic里面使用它们了
源码分析
userModel_gen.go
不要修改这个文件,每次构建api时会覆盖,如果要添加新的方法可以在userModel.go中修改
变量Var
|
|
对于有缓存的Model
|
|
接口
|
|
表结构体
User结构体对应表结构
defaultUserModel是userModel接口的实现,其具有默认生成的方法
|
|
函数
一个工厂函数,用于创建defaultUserModel对象
不带缓存Model
|
|
带缓存Model
|
|
方法
接口中方法在defaultUserModel对象的实现
|
|
缓存
Cache仅做单条数据的缓存
通常情况在etc中设置Cache和Redis,Cache是go-zero内置的配置对象,专门用于给Model服务,Redis则使用第三方redis库,作为中间件,可以做缓存也可以做其他作用,比如消息队列
带缓存的所有方法都跟不带缓存的Model不一样
带缓存的数据在缓存中找不到键的值时后才去查询DB
为了防止缓存雪崩,源码中对于未查到的数据会给插入一个*
值过期时间是1分钟,后续查询该键的请求发现是*
会直接返回。这样当多个请求打到缓存上时1分钟内只会触发一次数据库查询
添加缓存步骤
修改etc/yaml文件
|
|
修改internal/config.go
|
|
修改internal/svc/serviceContext.go,新建Model的时候添加缓存
|
|
索引优化
只有唯一索引可以生成默认优化
userModel.go
该文件用于添加自定义的方法
该文件中的customUserModel继承了userModel_gen.go文件中的defaultUserModel,还有一个UserModel的接口继承了userModel_gen.go文件中的userModel接口
类型type
|
|
所以customUserModel可以使用defaultUserModel的所有方法,要添加新方法则直接修改UserModel接口和给customUserModel添加方法就行了
默认生成函数
|
|
事务
查看sqlc的源码有如下方法
|
|
使用该方法来实现事务原子性,参数ctx用于做链路追踪,参数fn表示事务过程
返回err为nil的时提交,否则回滚到函数执行之前的状态
可以在userModel.go中封装这个方法来实现在logic中使用事务
|
|
默认生成Model的Insert不支持传入session,可以重写Insert函数,接收一个sqlx.Session参数,并将默认执行sql的对象修改为传入的sqlx.Session对象,这样就能通过一个session多次执行sql
|
|
另外需要使用同一个session去执行db操作
|
|
可以在函数里面判断一下如果传入的session是否为nil,如果是则直接使用新的连接conn.ExecCtx
TransactCtx源码首先在函数体中开启事务,最后使用defer recover来实现回滚,当执行sql时出现panic或者err时候回滚该事务
缓存的使用
对于主键字段缓存,会缓存整个结构体信息,而对于单索引字段(除全文索引)则缓存主键字段值。
类型转换规则
见文档
DB和Cache的使用
所有的方法都可以在末尾添加Ctx来使用ctx进行链路追踪
DB
特点
- 完成 queryField -> struct 的自动赋值,反射
- 批量插入「bulkinserter」
- 自带熔断
- API 经过若干个服务的不断考验
- 提供 partial assignment 特性,不强制 struct 的严格赋值
可以自己新建数据库连接,间原文
CRUD
CUD
|
|
R
|
|
Cache
类型
|
|
方法
- func (cc CachedConn) QueryRow(v interface{}, key string, query QueryFn) error:查看key是否存在,否则执行query
- func (cc CachedConn) QueryRowIndex(v interface{}, key string, keyer func(primary interface{}) string, indexQuery IndexQueryFn, primaryQuery PrimaryQueryFn) error:基于唯一索引查询
- keyer - 用主键生成基于主键缓存的key的方法
- indexQuery - 用索引从DB读取完整数据的方法,需要返回主键
- primaryQuery - 用主键从DB获取完整数据的方法
- func (cc CachedConn) DelCache(keys …string) error
- func (cc CachedConn) GetCache(key string, v interface{}) error
- func (cc CachedConn) Exec(exec ExecFn, keys …string) (sql.Result, error)
- func (cc CachedConn) ExecNoCache(q string, args …interface{}) (sql.Result, error)
- func (cc CachedConn) QueryRowNoCache(v interface{}, q string, args …interface{}) error
- func (cc CachedConn) QueryRowsNoCache(v interface{}, q string, args …interface{}) error
- func (cc CachedConn) SetCache(key string, val interface{}) error
- func (cc CachedConn) Transact(fn func(sqlx.Session) error) error