GORM 入门 | 青训营笔记

18 阅读2分钟

介绍

  • Gorm:一个迭代了十年的功能强大的 ORM框架

Gorm 基础使用

  • 安装:

    go get github.com/jinzhu/gorm
    
  • 连接数据库

    dsn := "root:root123@tcp(127.0.0.1:3306)/test_gorm?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        panic(err)
    }
    
    dsn := "root:root123@tcp(127.0.0.1:3306)/test_gorm?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open("mysql", dsn)
    if err != nil {
      panic(err)
    }
    
  • 自动迁移

    db.AutoMigrate(&Data{}) //Data是一个结构体
    db.AutoMigrate(&User{}, &Product{}, &Order{})
    db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&User{}) // 设置格式
    
  • db.Create(&Data{
        Id: "0001",
        Name: "01",
        Age: 10,
        Pic:  "/img/01.png",
    })
    
    • First 用于查询一条数据
    • 使用First查询不到会返回 ErrRecordNotFound
    var data Data
    db.First(&data) //第一个
    db.First(&data, 1 ) //根据主键查找
    db.First(&data, "Id = ?", "0001") //根据字段查找
    
    • Find 用于查询多条数据
    • 查询不到时返回的是一个空数组
    datas := make([]*Data, 10)  //容器声明//查找
    db.Where("name IN ?", []string{"01","02"}).Find(&datas)
    db.Where("name = ? AND age >= ?", "01","2").Find(&datas)
    db.Where("name LIKE ?","%jin%").Find(&datas)
    
    result := db.Where("Age > 10").Find(&datas) //查找并返回result
    fmt.Println(result.RowsAffected)    //返回找到的记录数(相当于 ‘len(datas)' )
    fmt.Println(result.Error)   //打印错误信息
    
  • db.Model(&data).Update("Id", "0002")
    db.Model(&data).Update( Data{ Id:"0002",Name:"02" } )
    db.Model(&data).Update( map[string]interface{}{ Id:"0002",Name:"02" } )
    db.Model(&data).Select(Name).Update( map[string]interface{}{ Id:"0002",Name:"02" } )    //更新选定字段
    ​
    db.Model(&datas{ID:2}).Update("Id", "0002") //更新数据集中的一个
    
    data.Id = "0001"
    db.Save(&data)
    
  • db.Delete(&data)
    db.Where("name LIKE ?", "%jin%").Delete(&datas) //删除数据集中的指定项
    
    • 软删除

      • 使用 gorm.DeletedAt 实现软删(软删后查不到)
      • 使用 Unscoped 可以查询被软删的数据
  • 冲突处理

    p := &Product{Code:"D42",ID:1}
    db.Clauses(clause.OnConflict{DoNothing:true}).Create(&p)
    

Gorm的约定

  • Gorm使用名为 ID 的字段作为主键
  • 使用结构体的蛇形负数作为表名
  • 字段名的蛇形作为列名
  • 使用CreatedAt、UpdateAt字段作为创建、更新时间

事务

  • 使用 Begin、Commit、Rollback 方法

    tx := db.Begin()    //开启事务
    //进行事务操作时,使用tx进行操作(直接操作db无法回滚)
    
    if err = tx.Create(&Data{Name:"01"}).Error; err != nil{
        tx.Rollback()   //遇到错误时回滚
        return
    }
    
    tx.Commit() //提交事务
    
  • Tansaction 方法用于自动提交事务,以避免漏写 Commit

    if err = db.Transaction(func(tx *gorm.DB) error{
            //匿名内部函数
        });
        err != nil{
            return
        }
    )
    

Hook

  • Hook 是在创建、查询、更新、删除等操作之前、之后自动调用的函数
  • 如果任何 Hook返回错误,GORM 将停止后续操作并回滚事务

提高事务性能

  • 对于写操作,为了保证数据的完整性,GORM会将他们封装在事务内运行,但这会降低性能,你可以使用 SkipDefaultTransaction 关闭默认事务

  • 使用 PrepareStmt 缓存预编译语句可以提高后续调用的速度,本机测试提高大概 35%

    db, err := gorm.Open(mysql.Open("username:password@tcp(localhost:9910)/database?charset=utf8"),
        &gorm.Config{
            SkipDefaultTransaction: true,
            PrepareStat: true
        },
    )
    if err != nil{
        panic("failed")
    }
    ​
    

GORM生态

image-20230128172844202