GORM(Go 的 ORM 库)连接数据库 | 青训营

122 阅读3分钟

前言

以前做Java开发的时候用的是JDBC连接数据库,现在Go语言是研发了自己原生的框架,Go框架三件套,HTTP框架HertzRPC框架Kitex以及ORM框架Gorm,这个章节篇幅很长,由于本人能力实在有限,所以只对Gorm框架进行了实践,其过程中会遇到很多困难,算是一节排坑吧

Start

以下实践过程以MySQL数据库为例

首先我们需要下载gorm的依赖:

go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql

这里我就掉坑了,因为是照着github的代码做的,所以go.mod写成了如下

Cache_54ce1e20323ac28c.jpg

然后就出现了错误

Cache_610536680c98a462.jpg

通过翻译知道了是循环调用依赖的结果,但是不知道怎么改正,因为是第一次学Go,不得已去网上搜索各种资料,但是并没有什么帮助,因为博客什么的都指出了这个错误,但是没有什么实质性的解决方案,这个BUG折腾了一个下午,不然这个踩坑日记早就出版了,最后还是求助了群里的小伙伴:

Screenshot_2023-08-13-00-56-15-61.jpg

由于主文件和go.mod调用同样的依赖,所以导致循环调用,解决方案就是重写go.mod,感谢小伙伴的热心帮助。

连接MySQL

这里都是默认大家都已经配置好了MySQL数据库,然后就是Gorm连接数据库

db, err := gorm.Open(mysql.Open("username:password@tcp(ip:port)/database"), &gorm.Config{})

我创建的sql数据库有一张表product,结构如下:

type Product struct{
	ID   uint 
	Code string
	Price uint
}

Gorm创建数据

在上面创建好的表中添加数据:

p := &Product{Code: "D42"}

res := db.Create(p)

注意这里Product需要用指针传值,在这里有一个小坑,就是MySQL设置的主键需要设置默认值,不然这里代码会报错,这个也很好解决,就在主键下面设置自增就好了。

image.png

Gorm删除数据

物理删除

db.Delete(&Product{}, 6) // delete from product where id = 6;
db.Delete(&Product{}, "6") // delete from product where id = 6;
db.Delete(&Product{}, []int{1, 2, 3}) // delete from product where id in (1, 2, 3);

他这个语法其实跟sql语法差不多,只是把类型换了换,一定要注意指针引用

软删除

  • GORM提供了gorm.DeletedAt 用于帮助用户实现软删
  • 拥有软删除能力的Model调用Delete时,记录不会被从数据库中真正删除。但 GORM会将DeletedAt置为当前时间,并且你不能再通过正常的查询方法找到该记录。
  • 使用Unscoped可以查询到被软删的数据
db.Unscoped().Where("Code = D42").Find(&Product{})

Gorm更新数据

db.Model(&Product{}).Where("ID > ?", 8).Update("Code", "DSB")  // 更新单列
db.Model(&Product{ID: 9}).Updates(Product{Code: "keji", Price: 169}) //更新多列

使用 Struct更新时,只会更新非零值,如果需要更新零值可以使用Map更新或使用Select选择字段。

Gorm查找数据

  • First的使用踩坑

使用First时,需要注意查询不到数据会返回ErrRecordNotFound。使用 Find查询多条数据,查询不到数据不会返回错误。

  • 使用结构体作为查询条件

当使用结构作为条件查询时,GORM只会查询非零值字段。这意味着如果您的字段值为0、"、false或其他零值该字段不会被用于构建查询条件,使用Map来构建查询条件。

pro := make([]*Product, 0)

小结

除了一开始的踩坑,其实后面的增删改查操作没什么困难的,学过数据库的都知道跟sql语句差不多,Go语言还是和其他有很大区别,比如就是零值的操作就不一样,需要分开论述,不过这些都可以无脑跳过,好久没用数据库了,至少上次用的还是SQL server 2008 R2 ,后来转用MySQL,觉得还不错,其实这些关系数据库都大差不差,数据库作为后端是比较核心的部分了,其实学的还非常浅,没有学到很深入的东西,继续加油吧!