Gorm架构-实践 | 青训营

76 阅读2分钟

--使用 GORM(Go 的 ORM 库)连接数据库,并实现增删改查操作,把实现过程整理成文章

一.数据库的连接

查询官方文档:gorm.cn/docs/ 查询其他文档:Gorm框架 教程 - 编程教程 (17bigdata.com)

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

func main() {
  // refer https://github.com/go-sql-driver/mysql#dsn-data-source-name for details
  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{})
}

dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"

根据数据库的相关信息填写,即可成功连接

插入数据

u := User{Name:"asd", Age:18}
db.Create(&u)

u1 := User{Age:20} //创建的时候没有写name,那么就会赋上默认值
db.Create(&u1)

要有效地插入大量记录,将一个 slice 传递给 Create 方法。 GORM 将生成单独一条 SQL 语句来插入所有数据,并回填主键的值

var users = []User{{Name: "jinzhu1"}, {Name: "jinzhu2"}, {Name: "jinzhu3"}} 

db.Create(&users) 
//输出ID
for _, user := range users { user.ID // 1,2,3 }

查询数据

查询第一条数据

var user User
//查询第一条记录
db.First(&user)
fmt.Printf("user:%#v\n", user)

查询所有的数据

//查询全部记录
var users []User
db.Find(&users)
fmt.Printf("users:%#v\n", users)

查询指定字段

但是返回的是整个结构体,只不过其他值都是零值

//查询指定字段
db.Select("name").Where("Age = ?", 18).Find(&users)
fmt.Println(users)

Tips:使用first查询单条数据时,查询不到数据会返回ErrRecordNotFound,而find不会返回错误。

使用结构体作为查询条件,只会查询非零值字段,0/false --> 使用Map来构建查询条件

u := &user{}
db.First(u)

users := make([]*User,0)
result = db.Where("age > 10").Find(&users)

result.RowsAffected为找到的记录数

db.Debug().Where("name = ?", "jinzhu").First(&user)

db.Debug().Where("name = ?", "jinzhu").Find(&user)

db.Debug().Where("name <> ?", "jinzhu").Find(&user) //查询name不等于jinzhu的所有记录

db.Debug().Where("name IN (?)", []string{"jinzhu", "jinzhu 2"}).Find(&user)

db.Debug().Where("name LIKE ?", "%jin%").Find(&user)//查询name包含jin的所有记录

db.Debug().Where("name = ? AND age >= ?", "jinzhu", "20").Find(&user)

db.Debug().Where("updated_at > ?", lastWeek).Find(&user)

oneDay, _ := time.ParseDuration("-24h") lastWeek := time.Now().Add(oneDay * 7)

数据库的软删除

gorm.DeletedAt.需要在struct中添加字段Deleted gorm.DeletedAt gorm:"index"

添加 gorm.DeleteAt 字段,从而自动获取 Soft-Delete 的能力

type Model struct {
  ID        uint           `gorm:"primaryKey"`
  CreatedAt time.Time
  UpdatedAt time.Time
  Deleted gorm.DeletedAt `gorm:"index"`
}

原生GORM,当我们调用 Delete 时, 指定的记录并不会从数据库中物理删除,而是会将 gorm.DeleteAt 字段的值设置为当前时间,在一般情况下,调用查询方法时不会被返回。 原来的 Delete 调用会被转换为一次 Update,自动处理了 delete_at 字段的更新逻辑。查询的时候,如果发现 model 中包含 gorm.DeleteAt 字段,也会自动加上 deleted_at IS NULL 作为 Where 条件。 如果需要查询到已经被软删除的记录,在 GORM 查询时加上 Unscoped

db.Unscoped().Where("age = 20").Find(&users)

gorm事务

提供Transaction方法自动提交事务,避免用户漏写Commit、Rollback