GORM是go语言中的一款ORM库,它为Web项目连接数据库从而进行数据库操作提供强大的功能和简洁的API,包括数据库连接、CRUD操作、事务管理等。接下来以简易抖音项目为例展示GORM的一些基础使用方法。
数据库连接
gorm库怎么安装比较简单,大家可以自行网上搜索安装即可。对于在web项目中使用gorm连接数据库,主要使用了gorm.Open()的这个接口:
从上图看到,我们以连接mysql数据库为例,数据库的连接信息先被保存到一个变量dsn中。从左到右的红色框中,第一个定义了连接数据库的用户名为root,其后跟着的是用户登陆数据库的密码。第二个红色框说明了我们通过IP地址加端口来连接到mysql的服务器。第三个红色框告诉了mysql我们想连接tiktok这个数据库。随后把这些信息作为参数传给gorm.Open()来连接数据库
CRUD操作
对于gorm的CRUD操作,一般做法是对于某个表的CRUD都会创一个相对应的.go文件来执行。比如说:
上图展示的是user这个表对应的user.go文件来存放CRUD操作。通过定义User结构体的TableName()函数来告诉mysql这里的CRUD是针对users表进行的。当然也有其他办法比如说在CRUD的时候通过.Model()来指向操作的对象是哪个表。
定义完TableName()后,NewUserDaoInstance()会被定义来创建一个UserDao实例进行CRUD操作,因为接下来CRUD函数的定义都是被定义为Dao结构体的函数,所以需要实例化一个Dao对象来执行这些操作。
Create
图中所示的create操作也是在上面定义好的user.go文件下的创建用户函数。从上由下看,第一个红框表示CreateUser()函数被定义为UserDao结构体的函数,所以执行的时候需要UserDao实例来进行调用。在函数内部,第二个红框为我们将要创建的user对象,定义好相对的数据后,执行create操作的是第三个红框里的db.Create()。db即为我们在连接数据库时gorm.Open()得到的mysql数据库对象。通过调用db.Create()接口,把想要创建的用户对象作为参数传入即可完成create操作。当然创建操作是有可能出错的,所以相对应的错误处理是不能省略的。
Retrieve
gorm提供了许多方法来支持SQL查询操作,以下列出其中的一些:
db.First();可以查询表中匹配的第一条记录,如果无匹配数据会返回gorm.RecordNotFound的错误,需要进行处理。db.Find();可以查询表中匹配的所有记录,所以返回的是一个列表,如果无匹配数据则会返回一个空列表,无错误返回db.Last();可以查询最后一条记录
查询中可以使用Where来限制查询的条件,比如说想要查询特定用户名的某一条用户数据:
result := db.Where("name == ?", username).Find(&users)
也可以使用.Order()来自定义排序的规则,用法与.Where()类似:
result := db.Opem("id desc").Find(&users)
使用Count来统计记录的条数:
result = db.Model(&User{}).Count(&count)
这里使用.Model()来指明执行操作的表,并定义了一个int64类型的变量count来作为Count()的参数传入获取记录的条数。
接着上面的创建操作,下面是执行根据username来查询user的查询过程:
这个查询函数也是定义为UserDao结构体的函数。主要操作为第二个红框的Find()接口。首先第一个红框定义了一个User结构体的列表变量users,因为我要用db.Find()来进行我的查询,而它返回的是一个列表对象。在查询操作中.Where()也应用其中来限制查询的条件为username。所以最终得到到返回结果为符合username的user对象。
我之所以选择使用db.Find()而不使用db.First()是因为Find()查询操作不会有RecordNotFound这个错误出现,所以我不需要考虑处理这个错误,我只需要判断Find()返回的查询结果列表是否为空来判断存不存在记录即可。
Update
gorm的更新操作也有两种方法,第一种是使用db.Save(),第二种是使用db.Update()。
db.Save()
使用这种方法前提是基于先查询,先查询出你想要更新的数据,然后对查询到的数据进行修改后,再把修改后的数据作为参数传入db.Save()来保存更新。
在这种更新操作下,你要确保更新的数据是存在表中的,不然就会变成创建操作了。这种更新操作个人觉得表复杂,所以更倾向于第二种方法。
db.Update()
可以看到,我这里执行的是usertoken的更新操作就是使用了db.Updates()接口,db.Updates()与db.Update()的区别就是在于你是更新一条数据还是更新多条。
Update()的方法有一个不同之处在于其只会更新非零值的字段,如果你传入update要更新的字段值为0,它则不会进行更新操作。要解决这个办法呢,就可以将结构体换成map[string]interface{}类型的map对象,像上图的第一个红框,每隔一段时间user的token字段就要进行更新,所以将要更新的LoginUserData结构体中的token字段定义为map类型对象再进行传入。在上图中,第二个红框为更新操作的语句,在Update()中也可以使用.Where来限制更新的条件。编写起来也是极其简单。
Delete
gorm的删除操作也是比较完善的,提供了软删除和完全删除的办法。gorm默认使用的是软删除策略也就是逻辑删除。
上图中实现的是简易抖音的评论删除操作。可以看到该删除是基于id删除的,所以.Where会用在删除操作上来限制删除条件。整个操作起来也是非常的简单,5行代码搞定。
上面说了这样的删除操作其实是逻辑删除,对于比较重要的数据逻辑删除可以更好的保存这些数据。逻辑删除后的数据在查询以及更新的时候是不会被查询到的。如果要进行完全删除也就是物理删除,可以调用gorm的.Unscoped()方法来实现:
result := db.Unscoped().Where("id=?", id).Delete(&comment)
总结
整体来说gorm的CRUD操作是十分方便且简单的,在连接好数据库之后就可以开始进行各种sql操作了。在实践之后也发现比较好上手,更多的功能以及用法还有待学习,不过目前对于CRUD也比较熟悉算是开了个好头!