River 的个人后端实践笔记|青训营

60 阅读4分钟

使用 GORM(Go 的 ORM 库)连接数据库,并实现增删改查操作

实践内容:

本文旨在记载关于在项目中使用GORM实现数据库功能的过程以及其中涉及到的问题和注意事项。

概念:

为Go语言开发设计的ORM(Object-Relational Mapping)框架。它可以用于数据库的连接、管理与操作。使用框架可以始开发过程简化--处理对象的逻辑要比处理各个数据文件更简便。

实践过程

  • 配置: 1024Code 线上工作台,go1.17
  • 项目结构:
    在此需要特别注意的是文件目录的结构。在这里很容易出现的报错,"/somefile is not in GOROOT"
    这是因为在运行时,指令是: go run GoProject, 运行的是文件夹的根目录,因此go mod 中的module要指向根目录,并且每个文件中的引用,都必须是引用文件从根目录开始的完整路径,而非一个文件名。

截屏2023-08-24 23.12.42.png

在本地配置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实例:
    可以通过以下三种方式:
  1. 直接在本地下载MySQL,并在编译软件中下载相关插件。
  2. 使用Docker生成MySQL实例。(而且方便未来的各种依赖管理)
  3. 本人使用: 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(待添加对象)


  1. 删除单条记录: res := db.Delete(&User{}, id) 根据条件删除: res := db.Where("条件 = ?", "slice名称").Delete(&S表名称{})
    软删除:如果在Model中使用了deleatedat字段,就可以通过db.Unscoped()命令来查看被软删除的信息。

  2. 改 (对数据库中的对象进行更新) 使用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的部分中可以看到详细的各种语句内部的逻辑。