ORM 框架 Gorm 初体验丨青训营笔记

133 阅读5分钟

image.png

ORM 框架 Gorm 初体验丨青训营笔记

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

一、本堂课重点内容

Gorm 是一个针对 Go 语言的 ORM 框架。Gorm 是一个简单、高效和可扩展的 ORM 框架,它使用了面向对象的方式与数据库交互,可以帮助开发人员简化数据库的操作。

Gorm 提供了一组强大的 API,可以让开发人员轻松的完成数据的增删改查,设计简洁,代码实现简单,可读性高,适合 Go 语言的开发风格。

二、详细知识点介绍

1. ORM 简介

ORM (Object-Relational Mapping) 是一种编程技术,用于在关系数据库和面向对象语言之间进行映射。

它为开发人员提供了一种方便的方法来操作数据库,而不需要直接写 SQL 语句。它通过映射数据库的表和字段到程序中的类和属性,从而使用面向对象的语法来操作数据库。

使用 ORM 可以让开发人员专注于业务逻辑,而不需要关心数据库技术细节,还能提高代码的可读性和可维护性。

2. Gorm的基本使用

  • Gorm 的安装

    go get -u gorm.io/gorm
    go get -u gorm.io/driver/sqlite
    
  • Gorm 的约定

    • 数据表名称:Gorm 会根据结构体的名称来确定数据表的名称,默认情况下 Gorm 会在结构体名称后加“s”作为数据表名称。例如:结构体名称为 User,那么数据表名称为 users。
    • 主键字段:Gorm 默认情况下会在数据表中寻找名为“ID”或“id”的字段作为主键字段,如果没有找到,则 Gorm 会自动创建一个名为“ID”的主键字段。
    • 字段名称:Gorm 会根据结构体中字段的名称来确定数据表中字段的名称,默认情况下 Gorm 会将字段名称转换为小写并将驼峰式命名法转换为下划线分隔命名法。例如:结构体中字段名称为 createdAt,那么数据表中字段名称为 created_at。
  • Gorm快速入门

    package main
    
    import (
      "gorm.io/gorm"
      "gorm.io/driver/sqlite"
    )
    
    type Product struct {
      gorm.Model
      Code  string
      Price uint
    }
    
    func main() {
      db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
      if err != nil {
        panic("failed to connect database")
      }
    
      // 迁移 schema
      db.AutoMigrate(&Product{})
    
      // 创建数据
      db.Create(&Product{Code: "D42", Price: 100})
    
      // 查询数据
      var product Product
      db.First(&product, 1) // 根据整形主键查找
      db.First(&product, "code = ?", "D42") // 查找 code 字段值为 D42 的记录
    
      // 更新数据 - 将 product 的 price 更新为 200
      db.Model(&product).Update("Price", 200)
      // 更新数据 - 更新多个字段
      db.Model(&product).Updates(Product{Price: 200, Code: "F42"}) // 仅更新非零值字段
      db.Model(&product).Updates(map[string]interface{}{"Price": 200, "Code": "F42"})
    
      // 删除数据 - 删除 product
      db.Delete(&product, 1)
    }
    
  • Gorm 通过驱动来连接数据库。驱动是指一种数据库驱动程序,用于实现数据库访问接口。Gorm 支持多种数据库驱动,如 MySQL,PostgreSQL,SQLite,SQLServer 等,若需要连接其他数据库,可以自行开发。

    // 连接SQLServer数据库
    import (
      "gorm.io/gorm"
      "gorm.io/driver/sqlserver"
    )
    
    // github.com/denisenkom/go-mssqldb
    dsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?databast=gorm"
    db, err := gorm.Open(sqlserver.Open(dsn),&gorm.Config{})
    
  • Gorm 创建数据

    • 插入一条数据
      user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()}
      
      result := db.Create(&user) // 通过数据的指针来创建
      
      user.ID             // 返回插入数据的主键
      result.Error        // 返回 error
      result.RowsAffected // 返回插入记录的条数
      
    • 插入多条数据
      var users = []User{{Name: "jinzhu"}, {Name: "wangqian"}, {Name: "Lucy"}} 
      DB.Create(&users)  
      for _, user := range users {   
          user.ID // 1,2,3 
      }
      
    • 定义字段默认值
      type User struct {
          ID         int64   
          Name       string `gorm:"default:galeone"` 
          Age        int64  `gorm:"default:18"`     
      }
      
  • Gorm 查询数据

    • 检索单个对象
      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;  
    
    result := db.First(&user)  
    result.RowsAffected // 返回找到的记录数  
    result.Error // returns error  
    
    // 检查 ErrRecordNotFound 错误  
    errors.Is(result.Error, gorm.ErrRecordNotFound)
    
    • 检索对象
    // 获取全部记录
    result := db.Find(&users)
    // SELECT * FROM users;
    
    db.Where(&User{Name: "jinzhu", Age: 0}).Find(&users)
    // SELECT * FROM users WHERE name = "jinzhu";
    

    注意 :当通过 struct 更新时,GORM 只会更新非零字段。 如果您想确保指定字段被更新,你应该使用 Select 更新选定字段,或使用 map 来完成更新操作。

  • Gorm 更新数据

    // 根据 `struct` 更新属性,只会更新非零值的字段
    db.Model(&user).Updates(User{Name: "hello", Age: 18, Active: false})
    // UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111;
    
    // 根据 `map` 更新属性
    db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
    // UPDATE users SET name='hello', age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111
    

注意 :当通过 struct 更新时,GORM 只会更新非零字段。 如果您想确保指定字段被更新,你应该使用 Select 更新选定字段,或使用 map 来完成更新操作。

  • Gorm 删除数据
    • 软删除
    // user 的 ID 是 `111`
    db.Delete(&user)
    // UPDATE users SET deleted_at="2013-10-29 10:23" WHERE id = 111;
    
    // 批量删除
    db.Where("age = ?", 20).Delete(&User{})
    // UPDATE users SET deleted_at="2013-10-29 10:23" WHERE age = 20;
    
    // 在查询时会忽略被软删除的记录
    db.Where("age = 20").Find(&user)
    // SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL;
    
    • 查找被软删除的记录
    db.Unscoped().Where("age = 20").Find(&users)
    // SELECT * FROM users WHERE age = 20;
    
    • 永久删除
    db.Unscoped().Delete(&order)
    // DELETE FROM orders WHERE id=10;
    

三、引用参考