使用 GORM(Go 的 ORM 库)连接数据库,并实现增删改查操作
实践内容:
本文旨在记载关于在项目中使用GORM实现数据库功能的过程以及其中涉及到的问题和注意事项。
概念:
为Go语言开发设计的ORM(Object-Relational Mapping)框架。它可以用于数据库的连接、管理与操作。使用框架可以始开发过程简化--处理对象的逻辑要比处理各个数据文件更简便。
实践过程
- 配置: 1024Code 线上工作台,go1.17
- 项目结构:
在此需要特别注意的是文件目录的结构。在这里很容易出现的报错,"/somefile is not in GOROOT"
这是因为在运行时,指令是: go run GoProject, 运行的是文件夹的根目录,因此go mod 中的module要指向根目录,并且每个文件中的引用,都必须是引用文件从根目录开始的完整路径,而非一个文件名。
在本地配置GORM
- 从GitHub下载
- 连接数据库:
gorm.io/zh_CN/docs/… 我将使用MySQL作为所有数据的储存中心。 ! 注意在下载时选择最新的版本(命令: go get gorm.io/gorm@v1.20.0 ) - MySQL 配置: 下载: go get gorm.io/driver/mysql 这是建立MySQL数据库的驱动。
MySQL 数据库结构设计
- 目标:储存用户信息
- 内容:不同用户的登录信息(如 用户名密码等), 以及每个用户产生的社交信息(如评论点赞发帖等)
- 设置主表和从表:
将所有用户注册信息设置为主表,主键是自动生成的顺序ID。将每个用户的其他信息,如自注册以来的消息和评论,设置为从表。 - 创建MySQL实例:
可以通过以下三种方式:
- 直接在本地下载MySQL,并在编译软件中下载相关插件。
- 使用Docker生成MySQL实例。(而且方便未来的各种依赖管理)
- 本人使用: 1024code平台提供的DSN信息进行MySQL数据库创建。
- GORM连接MySQL数据库:
使用结构体来定义类型。 首先是主表,因此使用model来添加自增的ID
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
接下来添加model后以相同方式定义主表
type User struct {
gorm.Model
Telephone string `gorm:"varchar(20);not null;unique" json:"telephone"`
Name string `gorm:"varchar(20);not null" json:"name"`
}
*使用db.migrate()方法可以简单地创建新表
4. 增
-
批量添加
待添加量 := []表名称{待添加对象} result := db.Create(&待添加量) -
单独添加
db.Create(待添加对象)
-
删
删除单条记录: res := db.Delete(&User{}, id) 根据条件删除: res := db.Where("条件 = ?", "slice名称").Delete(&S表名称{})
软删除:如果在Model中使用了deleatedat字段,就可以通过db.Unscoped()命令来查看被软删除的信息。 -
改 (对数据库中的对象进行更新) 使用Update()命令:
单列-- result := db.Model(&表名{}).Where(条件).Update(待更新键,新值)
多列-- 使用Updates()命令或者使用MySQL中的SET方法:
待更新对象.待更新键名 = 新值
db.Save(&待更新对象)
注意,Save()命令会保存零值! -
查
- 根据主键查询:
db.First(&待查slice的名称,主键) 以下为查询ID为1的用户注册信息的部分结果。
{{1 2023-08-24 00:16:21.536 +0800 CST 2023-08-24 00:16:21.536 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} 186******** River >
如果不设置主键,会默认返回表格中主键为1的slice(相对应的还有 db.Last()返回最后一条记录)。官方文档中不提倡这种做法,原因是没有筛选条件的情况下,函数会遍历整个表格,导致程序性能下降。
db.Take(&待查slice的名称)
返回一条slice,没有顺序。
-
根据map条件查询
使用db.Where(map[键的类型]interface{}map结构体).Find(&待查slice名称)指令。最后,本实践参考了GORM官方文档:https://gorm.io/zh_CN/docs/
中文版的官方文档很清晰易懂,并且在API的部分中可以看到详细的各种语句内部的逻辑。