记一次gorm版本不兼容踩坑经历

gorm的版本

我不知道大家有没有注意过,在不同的项目中引入的gorm 有时候git地址是不一样的,有gorm.io/gorm v1.25.5github.com/jinzhu/gorm,起初没怎么在意,直到有一天踩了一个坑。至于什么坑,我后面会演示出来。

两个版本的异同

原来gorm.io/gorm v1.25.5是Gorm 2.0及其以后的版本,而Gorm 版本 1 到 v1.9.16 一直保留在github.com/jinzhu/gorm这个仓库中,由于版本不兼容,所以留存了两个仓库

踩坑经历

在gorm2.0以后的版本,有的时候为了方便,对于不需要操作的数据,我会直接interface返回结果,比如这样

func (c CnkDbService) GetKeyword() (interface{}, error) {
	res := map[string]interface{}{}
	err := db.Table("table1").Where("id= ?", 1).Scan(&res).Error
	if err != nil {
		return nil, err
	}
	return res, nil
}

但是在低版本中我这样写,却一直报这样的错误[2024-01-23 15:42:35] unsupported destination, should be slice or struct 这个很让人头疼,查看源码,发现确实有这样的限制,不是slice和struct就会报错,但这明显是不符合规范的,
记一次gorm版本不兼容踩坑经历_第1张图片
因为在scan或者find或者first里面是允许传interface进去的

	err := db.Table("table1").Where("id= ?", 12).Scan(&res).Error
  • 排查这个问题花了很长时间,而且官方文档也给出了相关的例子,最后我认定可能是gorm版本不一致导致的。
var result map[string]interface{}
db.Model(&User{}).First(&result, "id = ?", 1)
  • 查看go.mod果然发现了端倪,原来是低版本导致的问题,后来对比两个版本的异同,发现了以下区别

两个版本的区别

open接收的参数不一致

// jinzhu
func Open(dialect string, args ...interface{}) (db *DB, err error) {}

// grom.io
func Open(dialector Dialector, opts ...Option) (db *DB, err error) {}

gorm.io 的 Find 方法在进行查找时,如果查找结果为空,不会报record not found,当接收函数为集合时,返回空集合;非集合时,返回零值。

// jinzhu
func (s *DB) Find(out interface{}, where ...interface{}) *DB {}

// gorm.io
func (db *DB) Find(dest interface{}, conds ...interface{}) (tx *DB) {}

where链查询处理不一样

dao.DB.Where("id = 1")
dao.DB.Where("name= ding").Where("age= 25").First(&User)

// jinzhu
// SELECT * FROM `user`  WHERE (name= ding) AND (age= 25) ORDER BY `user`.`id` ASC LIMIT 1

// gorm.io
// SELECT * FROM `user` WHERE id = 1 AND name = ding AND (age = 25) ORDER BY `user`.`id` LIMIT 1
// gormioDao.DB.Statement.Clauses = map[string]clause.Clause{}

你可能感兴趣的:(go)