例子:
1、生成user_model.go以及user_model_gen.go
假设一个普通的user表,生成user.sql
CREATE TABLE user
(
id bigint AUTO_INCREMENT,
username varchar(36) NOT NULL,
password varchar(64) default '',
UNIQUE name_index (username),
PRIMARY KEY (id)
) ENGINE = InnoDB COLLATE utf8mb4_general_ci;
进入Terminal终端,进入user.sql所在文件目录下,执行下面的命令
goctl model mysql ddl --src user.sql --dir .
生成的go文件如下:
2、分析user_model.go以及user_model_gen.go结构
2.1、user_model_gen.go
其中user_model_gen.go中主要包括userModel接口和defaultUserModel的结构体
type (
userModel interface {
Insert(ctx context.Context, data *User) (sql.Result, error)
FindOne(ctx context.Context, id int64) (*User, error)
FindOneByUsername(ctx context.Context, username string) (*User, error)
Update(ctx context.Context, data *User) error
Delete(ctx context.Context, id int64) error
}
defaultUserModel struct {
conn sqlx.SqlConn
table string
}
User struct {
Id int64 `db:"id"`
Username string `db:"username"`
Password string `db:"password"`
}
)
这里defaultUserModel的结构体实现了userModel接口,实现了五个方法。这里展示俩个:
func (m *defaultUserModel) Delete(ctx context.Context, id int64) error {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, id)
return err
}
func (m *defaultUserModel) FindOne(ctx context.Context, id int64) (*User, error) {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", userRows, m.table)
var resp User
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
2.2、user_model.go
user_model.go中一个UserModel接口中嵌套user_model_gen.go中的usermodel接口,
customUserModel结构体中一个user_model_gen.go中defaulUserModel的匿名指针类型字段。
最值得注意的是,这里提供了一个NewUserModel()函数,函数生成UserModel接口类型能指向的对象,也就是说我们最后能够使用的对象就是UserModel类型的,函数中return的是&customUserModel{}类型,所以就是customUserModel需要实现UserModel接口。这点也是我们后面扩展方法的原理所在。
var _ UserModel = (*customUserModel)(nil)
type (
// UserModel is an interface to be customized, add more methods here,
// and implement the added methods in customUserModel.
UserModel interface {
userModel
}
customUserModel struct {
*defaultUserModel
}
)
// NewUserModel returns a model for the database table.
func NewUserModel(conn sqlx.SqlConn) UserModel {
return &customUserModel{
defaultUserModel: newUserModel(conn),
}
}
3、在User_Model.go中扩展新的方法
由于go-zero官方在user_model_gen.go最上方中提示DO NOT EDIT,所以我们在user_model.go中增加扩展方法。
前文提到user_mode.go中的defaultUserModel已经实现了userModel接口的方法,又因为customUserModel包含*defaultUserModel,而此时UserModel中仅仅包含usermodel接口。所以此时customUsrModel完全实现了UserModel接口,现在我们要扩展
在UserModel接口中加入新方法签名,最后通过customUserModel接口体实现逻辑即可。
随后:
在serviceCtx结构体添加对应model,并在NewServiceContext里面正确返回实例
在logic代码调用svcCtx的实例我们自定义的方法