Golang学习(GORM)| 青训营笔记

66 阅读2分钟

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

Gorm

使用Go语言编写的ORM(Object-Relational Mapping)框架。用来操作数据库。

支持的数据库

默认支持 MySQL, SQLServer, PostgreSQL, SQLite。

通过驱动连接数据库,如果需要连接其它类型的数据库,可以复用/开发驱动。

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

func main() {
  // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
  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{})
}

基本操作

GORM 倾向于约定优于配置。默认情况下,GORM 使用 ID 作为主键,使用结构体名的 蛇形复数 作为表名,字段名的 蛇形 作为列名,并使用 CreatedAt、UpdatedAt 字段追踪创建、更新时间。

     // gorm.Model 的定义
        type Model struct {
          ID        uint           `gorm:"primaryKey"`
          CreatedAt time.Time
          UpdatedAt time.Time
          DeletedAt gorm.DeletedAt `gorm:"index"`
        }
    
    func (u table_struct) TableName() string {
	// 绑定 Mysql 表名为 users
	return "users"
    }
  • 创建
    user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()}

    result := db.Create(&user) // 通过数据的指针来创建

    user.ID             // 返回插入数据的主键
    result.Error        // 返回 error
    result.RowsAffected // 返回插入记录的条数
  • 查询

传结构体会丢弃零值,使用 map[string]interface{}则不会。

    // 获取第一条记录(主键升序)
    db.First(&user)
    // SELECT * FROM users ORDER BY id LIMIT 1;
    
    // 获取一条记录,没有指定排序字段
    db.Take(&user)
    
    // 获取最后一条记录(主键降序)
    db.Last(&user)
    
    result := db.First(&user)
    result.RowsAffected // 返回找到的记录数
    result.Error        // returns error or nil

    // 检查 ErrRecordNotFound 错误
    errors.Is(result.Error, gorm.ErrRecordNotFound)
  • 更新
// 条件更新
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;
  • 删除
// 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";

事务

事务(transaction)是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分区的工作单位。

  • Begin()
  • Rollback()
  • Commit()
  • Transection()

Hook

GORM 允许用户定义的钩子有 BeforeSave, BeforeCreate, AfterSave, AfterCreate 创建记录时将调用这些钩子方法。

func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
  u.UUID = uuid.New()

    if u.Role == "admin" {
        return errors.New("invalid role")
    }
    return
}

优化性能

在 open 的时候修改配置

  • SkipDefaultTransection
  • PrepareStmt