Go ORM框架 GORM 快速入门 | 青训营笔记

311 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 8 天

GORM 是基于 Go 语言的一个自动化的 ORM(Object Relational Mapping) 框架,用于对 Go 语言结构体和数据库字段之间的映射。

GORM 官方支持的数据库类型有四个

  1. MySQL(最流行的数据库)
  2. PostgreSQL(开源协议较为宽松,很多有定制数据库需求的公司都会基于PostgreSQL进行二开)
  3. SQLite(轻量级的关系型数据库,主要用于移动设备)
  4. SQL Server(微软推出的关系型数据库管理系统)

本文主要基于 MySQL 进行介绍。

官方文档地址:GORM - The fantastic ORM library for Golang, aims to be developer friendly.

(吐槽下,作为国产的ORM框架,中文文档居然没汉化完)

安装

命令行输入

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

其实先复制样例代码然后

 go mod tidy

也可以

约定与结构体定义

GORM 倾向于约定优于配置。默认情况下,GORM 会使用 ID 作为主键,使用结构体名的 蛇形复数 作为表名,字段名的 蛇形 作为列名。

(虽然个人觉得蛇形复数作为表名非常的抽象,而且这个复数也只是简单的加个s,所以基本是自己定义表名)

模型声明

 // Product 定义 gorm model
 type Product struct {
     ID    uint
     Code  string
     Price uint
 }

结构体实现 TableName() 方法来指定表名

 // TableName 为 model 指定表名
 func (p Product) TableName() string {
     return "product"
 }

可以使用 tag 来配置结构体字段的信息,tag 名大小写不敏感,但建议使用驼峰形式。

基本使用

连接数据库

 db, err := gorm.Open(
     mysql.Open("root:123456@tcp(127.0.0.1:3306)/gorm_learn?charset=utf8mb4&parseTime=True&loc=Local"),
     &gorm.Config{})
 if err != nil {
     panic("failed to connect database")
 }

gorm.Open() 的第一个参数是 DSN(数据资源名)

英文定义如下

DSN (Data Source Name)

The Data Source Name has a common format, like e.g. PEAR DB uses it, but without type-prefix (optional parts marked by squared brackets):

 [username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]

配置数据库自动更新

     err = db.AutoMigrate(&Product{})
     if err != nil {
         panic(err)
         return
     }

创建数据

 // Create
 db.Create(&Product{Code: "D42", Price: 100})

查找数据

 // Read
 var product Product
 db.First(&product, 1)
 //根据整形主键查找
 db.First(&product, "code=?", "D42") //查找ccode字段值为D42的记录

这里注意 First() Take() Last() 等方法会使用 limit 1,在查询不到数据时会返回 ErrRecordNotFound 。

而使用Find查询多条数据,查询不到数据不会返回错误。故推荐使用Find()查询数据再判断影响的数据行数。

 var products []Product
 db.Find(&products)
 if db.RowsAffected != 0 { // 查询到了数据
     // code
 }

更新数据

 // Update-将product的price更新为200
 db.Model(&product).Update("Price", 200)
 // Update-更新多个字段
 db.Model(&product).Updates(Product{Price: 200, Code: "F42"}) //仅更新非零值字段
 db.Model(&product).Updates(map[string]interface{}{"Price": 200, "Code": "F42"})

删除数据

 // Delete-删除 product
 db.Delete(&product, 1)