使用 grom 后所有操作数据库的代码都使用同一个表-链式调用

发布时间 2023-05-06 19:55:25作者: 自然对数

在写业务代码的时候一位同事写代码是这样的


func (p *PromptRepo) GetArtPrompt(ctx context.Context, options ...func(option *gorm.DB)) (articles []*model.ArticlePrompt, err error) {

	p.db = p.db.Table(model.ArticlePrompt{}.TableName())
	for _, option := range options {
		option(p.db)
	}

	err = p.db.Find(&articles).Error
	if err != nil {
		p.log.WithContext(ctx).Errorf("GetArtPrompt-err.%+v", err)
		return nil, err
	}
	return articles, nil
}

然后不可思议的事情就来了。竟然是链式调用的,也就是说 日志打印的SQL是

SELECT * FROM article_prompt WHERE name = 'xxx' AND age = 18 AND age = 28;

咋一看也不对。第二次的结果会把第一次的条件给拼上去,这就有点匪夷所思了。

新初始化的 *gorm.DB 或调用 新建会话方法 后,GORM 会创建新的 Statement 实例。因此想要复用 *gorm.DB,需要确保它们处于 新建会话模式,例如:

即把第一行的代码改为


db := p.db.WithContext(ctx).Table(model.ArticlePrompt{}.TableName())

参考
链式调用
使用 grom 后所有操作数据库的代码都使用同一个表-链式调用