GORM学习 | 青训营笔记

66 阅读3分钟

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

目录

  • 声明模型
  • 连接数据库
  • 创建记录
  • 查询
  • 更新
  • 删除

安装

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

import (
   "gorm.io/driver/mysql"
   "gorm.io/gorm"
)

声明模型

gorm:"column:id" 表示使用id作为数据库中对应字段的列名 同时还支持控制字段的读写权限,见模型定义 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.
结构体下面的那个成员则确定了对应数据库的库名

type Product struct {
   Id    uint64 `gorm:"column:id"`
   Code  string `gorm:"column:code"`
   Price uint   `gorm:"column:price"`
}

func (p *Product) TableName() string {
   return "product"
}

gorm.Model

GORM 定义一个 gorm.Model 结构体,其包括字段 IDCreatedAtUpdatedAtDeletedAt

// gorm.Model 的定义 
type Model struct {   
    ID        uint           `gorm:"primaryKey"`   
    CreatedAt time.Time   
    UpdatedAt time.Time   
    DeletedAt gorm.DeletedAt `gorm:"index"` 
} 

您可以将它嵌入到您的结构体中,以包含这几个字段。
例如:

type User struct {   
    gorm.Model   
    Name string 
} 
// 等效于 
type User struct {   
    ID        uint           `gorm:"primaryKey"`   
    CreatedAt time.Time   
    UpdatedAt time.Time   
    DeletedAt gorm.DeletedAt `gorm:"index"`   
    Name string 
}

连接数据库

GORM 官方支持的数据库类型有: MySQL, PostgreSQL, SQlite, SQL Server
这里我使用MySQL进行演示,其他见:连接到数据库 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.

func main() {
  dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
  db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
}
  • user是数据库用户名
  • pass是数据库密码
  • dbname是数据库名,需要提前创建,否则会报错
使用配置文件进行mysql的连接
  • /config/app.yml
mysql:
  dsn: user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local
  • /utils/system_init.go
package utils

import (
   "fmt"
   "ginChat/models"
   "github.com/spf13/viper"
   "gorm.io/driver/mysql"
   "gorm.io/gorm"
)

var db *gorm.DB

func InitConfig() {
   viper.SetConfigName("app")//指定配置文件名
   viper.AddConfigPath("config")//指定路径

   err := viper.ReadInConfig()

   if err != nil {
      fmt.Println(err)
   }

   fmt.Println("config mysql : ", viper.Get("mysql.dns"))
}

func InitMySQL() {
   DB, _ := gorm.Open(mysql.Open(viper.GetString("mysql.dsn")), &gorm.Config{})

   user := models.UserBasic{}
   DB.Find(&user)
   fmt.Println(user)
}

创建记录

db.AutoMigrate(&Product{})                   //自动建表,支持多个表同时创建
db.Create(&Product{Code: "D42", Price: 100}) //需要先建表

查询

GORM 提供了 FirstTakeLast 方法,以便从数据库中检索单个对象。当查询数据库时它添加了 LIMIT 1 条件,且没有找到记录时,它会返回 ErrRecordNotFound 错误

// 获取第一条记录(主键升序)
db.First(&user)
// SELECT * FROM users ORDER BY id LIMIT 1;

// 获取一条记录,没有指定排序字段
db.Take(&user)
// SELECT * FROM users LIMIT 1;

// 获取最后一条记录(主键降序)
db.Last(&user)
// SELECT * FROM users ORDER BY id DESC LIMIT 1;
db.First(&user, 10) 
// SELECT * FROM users WHERE id = 10;  

db.First(&user, "10") 
// SELECT * FROM users WHERE id = 10;  

db.Find(&users, []int{1,2,3}) 
// SELECT * FROM users WHERE id IN (1,2,3); 

更新

db.First(&user)  
user.Name = "jinzhu 2" 
user.Age = 100 db.Save(&user) 
// UPDATE users SET name='jinzhu 2', age=100, 
    birthday='2016-01-01', updated_at = '2013-11-17 21:34:10' WHERE id=111; 
// 条件更新 
db.Model(&User{}).Where("active = ?", true).Update("name", "hello") 
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE active=true;  

// User 的 ID 是 `111` 
db.Model(&user).Update("name", "hello") 
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111; 

// 根据条件和 model 的值进行更新 
db.Model(&user).Where("active = ?", true).Update("name", "hello") 
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true;

删除

删除一条记录时,删除对象需要指定主键,否则会触发 [批量 Delete],即删除所有符合的记录(很危险)(gorm.io/zh_CN/docs/…)

// Email 的 ID 是 `10` 
db.Delete(&email) 
// DELETE from emails where id = 10;  

// 带额外条件的删除 
db.Where("name = ?", "jinzhu").Delete(&email) 
// DELETE from emails where id = 10 AND name = "jinzhu";