使用 GORM(Go 的 ORM 库)连接数据库,并实现增删改查操作 | 豆包MarsCode AI刷题

74 阅读9分钟

GORM是一个流行的Go语言ORM(对象关系映射)库,它让数据库操作变得更加简单和高效。本文将介绍如何使用GORM连接数据库,并实现基本的增删改查(CRUD)操作。

1. 安装GORM

首先,需要安装GORM库。在Go项目中运行以下命令来安装GORM:

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

gorm.io/driver/sqlite 是 GORM 为 SQLite 数据库提供的驱动包,它允许 GORM 与 SQLite 数据库进行交互。以下是 gorm.io/driver/sqlite 的一些特点:

  1. 轻量级:SQLite 是一个轻量级的数据库,不需要独立的服务器进程或系统资源,数据库存储在一个单一的磁盘文件中。

  2. 内嵌式:SQLite 通常被嵌入到应用程序中,这意味着它不需要额外的数据库服务器就可以运行。

  3. 跨平台:SQLite 支持多种操作系统,包括 Windows、Linux、macOS 等。

2. 连接数据库

在Go程序中,需要导入GORM库,并建立与数据库的连接。

package main

import (
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
    "log"
)

var db *gorm.DB

func init() {
    var err error
    // 连接到SQLite数据库,如果文件不存在,会自动创建
    db, err = gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
    if err != nil {
        log.Fatal("Failed to connect to database:", err)
    }

    // 自动迁移模式
    db.AutoMigrate(&Product{})
}

type Product struct {
    gorm.Model
    Code  string
    Price uint
}

func main() {
    // 你的业务逻辑代码
}
  1. 导入包

    • "gorm.io/driver/sqlite":这是GORM为SQLite数据库提供的驱动,允许GORM与SQLite数据库进行交互。
    • "gorm.io/gorm":这是GORM库的主要包,提供了操作数据库的核心功能。
    • "log":这是Go标准库中的日志包,用于输出日志信息。
  2. 定义数据库变量

    • var db *gorm.DB:这里声明了一个全局变量db,类型为*gorm.DB,用于存储数据库连接实例。
  3. 初始化函数init()

    • func init() {:定义了一个名为init的函数。在Go语言中,init函数在程序启动时自动执行,用于初始化工作。
    • db, err = gorm.Open(sqlite.Open("test.db"), &gorm.Config{}):这里使用GORM的Open函数连接SQLite数据库。sqlite.Open("test.db")指定了数据库文件的名称,如果test.db文件不存在,SQLite会自动创建它。&gorm.Config{}是一个配置结构体,可以在这里配置GORM的行为,但在这个例子中使用了默认配置。
    • if err != nil {:检查连接数据库是否出现错误。
    • log.Fatal("Failed to connect to database:", err):如果连接失败,使用log.Fatal函数输出错误信息并停止程序执行。
    • db.AutoMigrate(&Product{}):调用AutoMigrate方法自动创建或更新数据库表结构。这里传入了Product结构体的地址,GORM会根据Product结构体的定义创建相应的数据库表。
  4. 定义模型Product

    • type Product struct {:定义了一个名为Product的结构体,它将对应数据库中的一个表。
    • gorm.Model:这是GORM提供的模型,包含了一些基本的字段,如IDCreatedAtUpdatedAtDeletedAt
    • Code string:定义了一个名为Code的字段,类型为字符串。
    • Price uint:定义了一个名为Price的字段,类型为无符号整数。
  5. 主函数main()

    • func main() {:定义了程序的主入口函数。
    • // 你的业务逻辑代码:这里是一个占位符,表示你可以在这里添加你的业务逻辑代码,例如添加、查询、更新或删除Product记录。

3. 定义模型

在GORM中,需要定义一个模型(Model),它对应数据库中的一个表。

type Product struct {
    gorm.Model
    Code  string
    Price uint
}

这里定义了一个Product模型,包含IDCreatedAtUpdatedAtDeletedAt(由GORM自动管理)和两个自定义字段CodePrice

4. 增删改查操作

创建(Create)

func createProduct() {
    product := Product{Code: "D42", Price: 100}
    result := db.Create(&product) // 使用Create方法添加记录
    if result.Error != nil {
        log.Fatal(result.Error)
    }
}
  1. 函数定义

    • func createProduct() {:定义了一个没有参数和返回值的函数 createProduct
  2. 创建 Product 实例

    • product := Product{Code: "D42", Price: 100}:在这里,创建了一个 Product 类型的实例 product,并初始化了它的 Code 和 Price 字段。Code 被设置为 "D42"Price 被设置为 100
  3. 插入数据库

    • result := db.Create(&product):这行代码使用全局变量 db(之前在 init 函数中初始化的数据库连接)的 Create 方法将 product 实例添加到数据库中。Create 方法接受一个指向要创建的对象的指针,并返回一个 Result 对象,该对象包含操作的结果。
    • db.Create 方法会自动将 product 对象的字段映射到数据库表的列,并执行插入操作。
  4. 错误处理

    • if result.Error != nil {:这行代码检查 Create 操作是否返回了错误。
    • log.Fatal(result.Error):如果 result.Error 不为 nil,表示插入操作失败,函数将使用 log.Fatal 输出错误信息,并终止程序执行。log.Fatal 会打印日志信息并调用 os.Exit(1) 退出程序,这意味着程序会因为错误而异常终止。

读取(Read)

func findProduct() {
    var product Product
    result := db.First(&product, 1) // 根据ID查询
    if result.Error != nil {
        log.Fatal(result.Error)
    }
    log.Println(product)
}
  1. 函数定义

    • func findProduct() {:定义了一个没有参数和返回值的函数 findProduct
  2. 声明 Product 变量

    • var product Product:声明了一个名为 product 的变量,类型为 Product。这个变量将用来存储从数据库查询到的记录。
  3. 查询数据库

    • result := db.First(&product, 1):这行代码使用全局变量 db(之前在 init 函数中初始化的数据库连接)的 First 方法查询数据库中 ID 为 1 的 Product 记录。First 方法接受两个参数:第一个参数是一个指向 Product 结构体实例的指针,用于存储查询结果;第二个参数是查询条件,这里使用数字 1 作为条件,表示查询 ID 字段值为 1 的记录。
    • db.First 方法会根据提供的主键值在数据库中查找对应的记录,并将查询结果映射到传入的 product 变量中。
  4. 错误处理

    • if result.Error != nil {:这行代码检查 First 操作是否返回了错误。
    • log.Fatal(result.Error):如果 result.Error 不为 nil,表示查询操作失败,函数将使用 log.Fatal 输出错误信息,并终止程序执行。log.Fatal 会打印日志信息并调用 os.Exit(1) 退出程序,这意味着程序会因为错误而异常终止。
  5. 输出查询结果

    • log.Println(product):如果查询成功且没有错误,这行代码使用 log.Println 函数打印查询到的 product 变量的内容。这将输出 Product 结构体的所有字段和值,包括自动生成的 IDCreatedAtUpdatedAt 等字段。

更新(Update)

func updateProduct() {
    var product Product
    db.First(&product, 1) // 先查询
    result := db.Model(&product).Update("Price", 200) // 更新Price字段
    if result.Error != nil {
        log.Fatal(result.Error)
    }
}
  1. 函数定义

    • func updateProduct() {:定义了一个没有参数和返回值的函数 updateProduct
  2. 声明 Product 变量

    • var product Product:声明了一个名为 product 的变量,类型为 Product。这个变量将用来存储从数据库查询到的记录。
  3. 查询数据库

    • db.First(&product, 1):这行代码使用全局变量 db(之前在 init 函数中初始化的数据库连接)的 First 方法查询数据库中 ID 为 1 的 Product 记录。First 方法接受两个参数:第一个参数是一个指向 Product 结构体实例的指针,用于存储查询结果;第二个参数是查询条件,这里使用数字 1 作为条件,表示查询 ID 字段值为 1 的记录。
    • db.First 方法会根据提供的主键值在数据库中查找对应的记录,并将查询结果映射到传入的 product 变量中。
  4. 更新数据库记录

    • result := db.Model(&product).Update("Price", 200):这行代码使用 db 的 Model 方法和 Update 方法更新 Product 记录的 Price 字段。Model 方法接受一个指向 Product 结构体实例的指针,指定要更新的模型,Update 方法接受字段名和新值作为参数,这里将 Price 字段更新为 200
    • db.Model(&product).Update 方法会生成一个 SQL 更新语句,并执行它来更新数据库中的记录。
  5. 错误处理

    • if result.Error != nil {:这行代码检查 Update 操作是否返回了错误。
    • log.Fatal(result.Error):如果 result.Error 不为 nil,表示更新操作失败,函数将使用 log.Fatal 输出错误信息,并终止程序执行。log.Fatal 会打印日志信息并调用 os.Exit(1) 退出程序,这意味着程序会因为错误而异常终止。

删除(Delete)

func deleteProduct() {
    var product Product
    result := db.First(&product, 1) // 先查询
    result = db.Delete(&product, 1) // 删除记录
    if result.Error != nil {
        log.Fatal(result.Error)
    }
}
  1. 函数定义

    • func deleteProduct() {:定义了一个没有参数和返回值的函数 deleteProduct
  2. 声明 Product 变量

    • var product Product:声明了一个名为 product 的变量,类型为 Product。这个变量将用来存储从数据库查询到的记录。
  3. 查询数据库

    • result := db.First(&product, 1):这行代码使用全局变量 db(之前在 init 函数中初始化的数据库连接)的 First 方法查询数据库中 ID 为 1 的 Product 记录。First 方法接受两个参数:第一个参数是一个指向 Product 结构体实例的指针,用于存储查询结果;第二个参数是查询条件,这里使用数字 1 作为条件,表示查询 ID 字段值为 1 的记录。
    • db.First 方法会根据提供的主键值在数据库中查找对应的记录,并将查询结果映射到传入的 product 变量中。
  4. 删除数据库记录

    • result = db.Delete(&product, 1):这行代码使用 db 的 Delete 方法删除之前查询到的 Product 记录。Delete 方法接受两个参数:第一个参数是一个指向 Product 结构体实例的指针,指定要删除的记录;第二个参数是删除条件,这里使用数字 1 作为条件,表示删除 ID 字段值为 1 的记录。
    • db.Delete 方法会生成一个 SQL 删除语句,并执行它来删除数据库中的记录。
  5. 错误处理

    • if result.Error != nil {:这行代码检查 Delete 操作是否返回了错误。
    • log.Fatal(result.Error):如果 result.Error 不为 nil,表示删除操作失败,函数将使用 log.Fatal 输出错误信息,并终止程序执行。log.Fatal 会打印日志信息并调用 os.Exit(1) 退出程序,这意味着程序会因为错误而异常终止。

5. 运行程序

main函数中调用上述函数,执行CRUD操作:

func main() {
    createProduct()
    findProduct()
    updateProduct()
    deleteProduct()
}