GORM 入门 | 青训营

76 阅读3分钟

简介

GORM 是一个强大的 Go 语言 ORM(Object-Relational Mapping)库,它提供了简单且直观的 API,帮助开发者轻松地与数据库进行交互。目前 GORM 官方支持的数据库类型有:MySQL, PostgreSQL, SQLite, SQL Server 和 TiDB。由于本次项目我们使用的是 MySQL,所以我们下面就以 MySQL 为例子进行学习。

安装

首先,我们需要安装 GORM。在终端中运行以下命令:

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

这将安装 GORM 及对应的 MySQL 驱动程序。

连接数据库

我们可以使用

dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

连接数据库,dsn 是指 Data Source Name。

但是我们在工程里,一般不会每次使用都去使用 Open 获取数据库连接,因为 Open 会返回一个 *gorm.DB 类型的值,我们可以保存下来,并提供公共方法返回 DB 对象的指针。

数据库的连接池由 GORM 自己来维护,而 GORM 则是使用的 database/sql 对连接池进行维护,如果想要设置,GORM 也提供了方法

基本使用

定义模型

在使用 GORM 进行数据库操作之前,我们需要定义模型,也就是 MVC 模式中的 Model。Go中使用结构体进行定义,每个 Model 对应数据库中的一个表。

type User struct {
    gorm.Model
    Name  string
    Email string
}

这里我们定义了一个名为 User 的模型,它包含了 Name 和 Email 两个字段。gorm.Model 是一个内置的 GORM 模型,它包含了一些常用的字段,如ID、CreatedAt 和 UpdatedAt。如果不需要,我们也可以自己写。

func main() {
    // ...
    user := User{Name: "John Doe", Email: "john@example.com"}
    result := db.Create(&user)
    if result.Error != nil {
        panic("无法创建记录")
    }

    fmt.Println("记录创建成功!")
}

使用 db.Create() 方法可以创建新数据并保存到数据库中,通过返回值我们可以检查是否执行成功。而 result.Error 则包含具体错误的信息。

使用 Delete 方法我们可以删除记录。

func main() {
    // ...
    result = db.Delete(&user)
    if result.Error != nil {
        panic("无法删除记录")
    }

    fmt.Println("记录删除成功!")
}

func main() {
    // ...
    var user User
    result := db.Where("id = ?", 1).First(&user)
    user.Email = "newemail@example.com"
    result = db.Save(&user)
    if result.Error != nil {
        panic("无法更新记录")
    }
    fmt.Println("记录更新成功!")
}

这里我们先从数据库中读取到 ID 为 1 的用户,然后将其 Email 字段更新。

注意 Save 会保存所有的字段,即使字段是零值。而且 Save 是一个符合语句,如果传入的对象引用并没有包含主键,GORM 会使用前面我们提到的 Create 新建记录,否则才会进行更新。

Updates 方法则不同,它不会更新零值字段。

db.Model(&user).Updates(User{Name: "", Email: "newemail@example.com"})

由于这里使用的 Name 是一个字符串零值,所以 GORM 并不会将数据库中对应的数据更新。但是 GORM 还是提供了一种方式,让我们可以实现置零的需求。那就是使用 map[string]interface{}

db.Model(&user).Updates(map[string]interface{}{"name": "", "email": "newemail@example.com"})

GORM 使用 First 获取第一条数据,如果不存在,则返回 ErrRecordNotFound 错误。

func main() {
    // ...
    var user User
    result := db.Where("id = ?", 1).First(&user)
    if result.Error != nil {
        panic("无法找到记录")
    }
    fmt.Println("记录找到!")
    fmt.Println("姓名:", user.Name)
    fmt.Println("邮箱:", user.Email)
}

在上面的示例中,我们使用 db.First() 方法查询 ID 为 1 的记录,并将结果保存到 user 变量中,注意我们要传入 user 的引用,而 Where则定义了查询的条件。

如果想要获取多条数据,我们需要使用Find方法,并且需要传入对象的切片,这很好理解,我们总不能将多个对象赋值给一个对象。

注意一直到 First 或者 Find 方法,SQL语句才会真正开始执行。