goctl生成的sqlx方法不够用,如何扩展新的方法

本文详细介绍了如何使用Go语言的ORM工具生成用户模型文件,包括user_model.go和user_model_gen.go的结构分析,以及如何在User_Model.go中扩展新的数据库操作方法。重点讲解了customUserModel结构和NewUserModel函数的作用,以实现在服务上下文中使用自定义的数据库模型进行操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

例子:

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的实例我们自定义的方法


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值