GORM入门指南 | 青训营

81 阅读2分钟

GORM是Go语言中一个强大的ORM(Object Relational Mapping,对象关系映射)库,能够帮助开发者在Go程序中实现结构体与关系数据库数据之间的映射。GORM提供了很多API,这使得操作数据库变得简单方便。下面主要介绍GORM的安装和基本的用法。

安装GORM

在Go语言环境中,使用以下命令安装GORM:

go get -u gorm.io/gorm

连接数据库

与MySQL数据库建立连接:

// 安装驱动
go get -u gorm.io/driver/mysql

// 连接数据库
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", user,  password, host, port, dbName,)

DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})

if err != nil {
    fmt.Println("Failed to connect mysql")
}

注:user和password指的是访问MySQL数据库的用户名和密码,host和port指访问MySQL的主机地址和端口(默认是3306),dbName是数据库名字。

模型定义

在GORM中,可以通过Go结构体来表示数据库表,此时的结构体称为模型。该结构体中的字段与表的列一一对应。

type User struct {
	ID uint
	Name string
	Age int
	Hobby string
}

注:如果模型中存在字段ID,默认将其作为主键。

GORM中内置了一个gorm.Model结构体。我们可以在自己的模型中嵌入该结构体。

// gorm.Model 定义
type Model struct {
  ID          uint
  CreatedAt   time.Time
  UpdatedAt   time.Time
  DeletedAt   *time.Time
}

注:CreatedAt,UpdatedAt,DeletedAt分别用于追踪记录的创建,更新和删除时间。

type Message struct {
  gorm.Model
  UserId     int64    `gorm:"not null"`
  Content    string
}

// 上面的Message模型等同于
type Message struct {
  ID          uint      
  CreatedAt   time.Time
  UpdatedAt   time.Time
  DeletedAt   *time.Time
  UserId      int64      `gorm:"not null"`
  Content     string
}

注:(1) 在使用结构体声明模型时,gorm支持使用标记设置字段的相关属性。比如,通过gorm:"not null"限制UserId不能为空。(2) 在不指定列名的情况下,GORM 默认使用字段名的snake_case作为列名。比如,UserId对应的数据库表中的列名为user_id。Content字段对应的列名为content。

操作数据库

// 自动迁移
DB.AutoMigrate(&User{})

// 插入一条记录
u1 := UserInfo{1, "LiHua", 10, "足球"}
DB.Create(&u1)

// 查询记录
var u2 User
DB.Where("id = ?", 1).Find(&u2)
DB.First(&u2)

// 更新记录
DB.Model(&u2).Update("hobby", "篮球")

// 删除记录
DB.Delete(&u2)

注:如果模型有DeleteAt字段,当调用Delete函数删除记录时,不会将其直接从数据库删除,而是设置DeleteAt字段为当前的时间。

GORM中以使用 Raw 方法执行原生查询 SQL,并通过Scan获取结果。

var u User
DB.Raw(`SELECT id, name, age FROM users WHERE id = ?`, 1).Scan(&u)

注:在GORM中,表名默认是结构体名称的复数,比如这里模型User对应的数据库表的表名为users。

总结:通过本文,我们学习到GORM基本的使用方式。除了上述介绍的简单CRUD操作外,GORM中还支持更复杂的查询和关联操作,以及事务,钩子函数等,有兴趣的读者可以通过阅读官方文档(gorm.io/zh_CN/docs/… )进行更深入的学习和实践。