什么是GORM?
我们经常需要在项目中连接到数据库,例如python项目,java项目,在项目中进行数据库操作总是需要编写sql代码,非常麻烦。 GORM是基于Golang的ORM操作库,使用简单,它将struct类型和数据库表记录进行映射,操作数据库的时候不需要直接手写sql代码。
前置准备:
- MYSQL
- NAVICAT(数据库可视化工具)
- GO
- vscode及对应的go插件和工具(见另一篇文章)
GORM连接mysql
首先创建一个go的项目,我创建一个文件夹gorm_study作为项目文件夹,在vscode打开文件夹后在终端输入go mod init gorm_study来初始化go.mod文件。
PS C:\Users\12777\vscodeProjects\go\gorm_study> go mod init gorm_study
go: creating new go.mod: module gorm_study
go: to add module requirements and sums:
go mod tidy
接下来我在终端设置了一下GOPROXY来使用国内镜像源下载包
go env -w GOPROXY=https://goproxy.cn
操作MySQL需要两个go包,我们使用go tidy或者go get来获取:
- MySQL驱动包
- GORM包 在终端输入命令来下载两个包:
//安装MySQL驱动
go get -u gorm.io/driver/mysql
//安装gorm包
go get -u gorm.io/gorm
当然,我们也可以在项目中直接引入包后使用go mod tidy命令来一键导入。
接下来导入包:
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
使用gorm连接数据库分为两步——1.配置DNS 2.使用gorm.Open连接数据库:
配置DSN(DATA SOURCE NAME)
类似于别的语言连接数据库的连接字符串,dsn中指定了数据库的连接信息。DSN的格式:
[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]
例如:
root:123456@tcp(localhost:3306)/test?charset=utf8&parseTime=True&loc=Local
连接数据库
创建一个*gorm.DB类型的全局变量,用于存放Open返回的结果。我们把连接操作放在init函数中,把创建的数据库连接赋值给DB。并在main函数中打印DB结果。
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
"fmt"
)
var DB *gorm.DB
func init(){
//配置MySQL连接参数
username := "root" //账号
password := "0920" //密码
host := "127.0.0.1" //数据库地址,可以是Ip或者域名
port := 3306 //数据库端口
Dbname := "go_test" //数据库名
timeout := "10s" //连接超时,10秒
//拼接下dsn参数, dsn格式可以参考上面的语法,这里使用Sprintf动态拼接dsn参数,因为一般数据库连接参数,我们都是保存在配置文件里面,需要从配置文件加载参数,然后拼接dsn。
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local&timeout=%s", username, password, host, port, Dbname, timeout)
//连接MYSQL, 获得DB类型实例,用于后面的数据库读写操作。
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("连接数据库失败, error=" + err.Error())
}
DB = db
}
func main(){
fmt.Println("hello, gorm!")
fmt.Println(DB)
}
终端给我返回了如下结果,说明连接已经成功创建!
[Running] go run "c:\Users\12777\vscodeProjects\go\gorm_study\gorm.go"
hello, gorm!
&{0xc0001ba510 <nil> 0 0xc0000636c0 1}
现在我们已经有了数据库go_test和Go项目的连接。接下来我需要对数据库进行创建表以及表里的增删改查操作。
GORM实现数据库操作
Gorm中使用结构体Go Struct映射到数据库表来简化数据库交互,因此我们首先需要在代码中定义结构体模型。接下来我们定义一个Student结构体,对应数据库的Student表。
//定义一个结构体,用于映射数据库表
type Student struct{
Id uint // 主键
Name string// 姓名
Age int// 年龄
}
在GORM模型中:
- 具体数字类型如
uint、string和uint8可以直接使用。 - 指向
*string和*time.Time类型的指针表示可空字段。 - 来自
database/sql包的sql.NullString和sql.NullTime用于具有更多控制的可空字段。 CreatedAt和UpdatedAt是特殊字段,当记录被创建或更新时,GORM 会自动向内填充当前时间。- Non-exported fields (小写字母开头的字段) are not mapped
创建表
有了模型后就可以向数据库中创建这样一个Student表,使用代码:
func main(){
DB.AutoMigrate(&Student{})//自动迁移表结构
}
增加一条数据
使用Create()函数来创建records,假设我们想创建张三的记录,就先创建张三的结构体:
stu := Student{Name:"李四", Age: 17}// 定义一个结构体变量
接下来使用Create()创建:
DB.Create(&stu)
这时候就可以看到我们的数据库中已经出现了新的记录:
删除一条数据
删除就比较简单了,直接使用Delete与之前查询出来的模型变量绑定记录。
DB.Delete(&stu)
也可以不用提前查询,直接使用Where条件删除数据,这样就不用提前定义模型变量。但是其核心原理是一样的。
DB.Where("Name = ?","张三").Delete(&Student{})
查询数据
首先定义一个接受查询结果的结构体变量
stu := Student{}
- 查询一条记录——Take()
DB.Take(&stu)
- 根据ID排序,返回第一条记录——First()
DB.First(&stu)
- 根据ID排序(倒序),返回第一条记录——Last()
DB.Last(&stu)
- 指定Where条件——Where()
DB.Where("Name = ?","张三").Take(&stu)
如下返回了查询结果:
修改数据
- 查询的Where()来把数据查询出来并放在结构体中,结合保存函数Save()可以实现数据更新:
var stu Student//
DB.Where("Name =?","张三").Take(&stu)//查找到数据
stu.Age = 20//修改数据
DB.Save(&stu)//保存数据
执行完以上函数后再次执行查询,可以看到张三的年龄已经被修改为了20
- 除了Save还可以使用Update来更新,同样有使用Where查询后更新
DB.Model(&stu).Where("Id = ?","1").Update("Name","李四")
总结
经过这次数据库GORM实战,我不仅复习了数据库的知识,也熟悉了go语言与数据库的交互方式,技术果然是在不断发展的,相比在本科时学习的基础是远远不够的,很多新技术还需要不断地学习,保持终生学习的态度,不过以前学习过的知识打下了基础,所以在听这节课才不会吃力。
另外表扬一下vscode的豆包插件,帮我写注释和增删改查也太方便了,不仅方便,在我不理解教程代码的时候,提示的注释能帮助我理解知识,极大的提升了我的学习效率和编程效率。