文章目录
- 一、什么是GORM?
- 二、GORM连接mysql以及AutoMigrate创建表
- 三、查询
- 1、检索此对象是否存在于数据库(First,Take,Last方法)
- 2、Find()方法检索
- 3、根据指定字段查询
- 四、更新
- 1、Save() 保存多个字段
- 2、更新单个字段
- 五、删除
一、什么是GORM?
GORM 是 Go 语言中一个非常流行的 ORM(对象关系映射)库,它提供了一种简单而强大的方式来将 Go 结构体映射到数据库表,并提供了丰富的方法来操作数据库,比如查询、插入、更新和删除数据等。
二、GORM连接mysql以及AutoMigrate创建表
使用GORM之前先获取包:
go get "gorm.io/driver/mysql"
go get "gorm.io/gorm"
数据库的连接:
db, _ = gorm.Open(mysql.New(mysql.Config{DSN: "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local",}), &gorm.Config{SkipDefaultTransaction: true, // 禁用默认事务(提高运行速度)DisableForeignKeyConstraintWhenMigrating: true, // 禁用外键约束NamingStrategy: schema.NamingStrategy{//TablePrefix: "t_", // 表名前缀,`User` 的表名应该是 `t_users`SingularTable: true, // 使用单数表名,启用该选项},})
使用AutoMigrate自动创建表,在这里我们就要知道GORM里的模型是什么意思。
模型是使用普通结构体定义的。
也就是说,数据库中的表是根据我们自己建立的结构体生成的,我们可以在设计结构体的时候,在后边加上gorm的一些限制,然后自动迁移就可以在数据库中生成了。
gorm.Model
type Model struct {ID uint `gorm:"primarykey"`CreatedAt time.TimeUpdatedAt time.TimeDeletedAt DeletedAt `gorm:"index"`
}
这是gorm已经定义好的结构体,可以直接使用。
案例1:创建一个用户表自动迁移到数据库中。
type User struct {gorm.ModelName stringAge int
}func main() {db.AutoMigrate(&User{}) //自动迁移这个表user := User{Name: "张三",Age: 18,}rest := db.Create(&user)fmt.Println(user.ID) // 主键IDfmt.Println(rest.RowsAffected)fmt.Println(rest.Error)
}
案例2:自动创建一个嵌套的表组合。
type User struct {gorm.ModelName stringAge int
}type Work struct {UserWork string
}func main() {err := db.AutoMigrate(&Work{}) //自动迁移这个表if err != nil {fmt.Println(err)}work := Work{User: User{Name: "张三", Age: 18}, Work: "程序员"}db.Create(&work)fmt.Println(work.ID)
}
三、查询
以下所有操作的基本数据库信息如下:
1、检索此对象是否存在于数据库(First,Take,Last方法)
GORM 提供了First、Take、Last
方法,以便从数据库中检索单个对象。当查询数据库时它添加了 LIMIT 1 条件,且没有找到记录时,它会返回 ErrRecordNotFound
错误。
//查询张三是否在数据库中//SELECT * FROM `work` WHERE name = '张2三' AND `work`.`deleted_at` IS NULL ORDER BY `work`.`id` LIMIT 1var work1 Workresult := db.Where("name = ?", "张三").First(&work1)if result.Error != nil {if errors.Is(result.Error, gorm.ErrRecordNotFound) {fmt.Println("没找到记录")return}fmt.Println(result.Error)return}fmt.Println(result.RowsAffected) // 受影响的行数
2、Find()方法检索
// 查询age=20的所有的信息var works []Workresult = db.Where("age = ?", 20).Limit(1).Find(&works)if result.Error != nil {if errors.Is(result.Error, gorm.ErrRecordNotFound) {fmt.Println("没找到记录")return}fmt.Println(result.Error)return}fmt.Println(result.RowsAffected)for i, work := range works {fmt.Println(i, work)}
3、根据指定字段查询
// 指定结构体查询字段var work2 []Workresult11 := db.Select("name,age").Where("age = ?", 20).Limit(2).Find(&work2)if result.Error != nil {if errors.Is(result11.Error, gorm.ErrRecordNotFound) {fmt.Println("没找到记录")return}fmt.Println(result11.Error)return}fmt.Println(result11.RowsAffected)for i, work := range work2 {fmt.Println(i, work)}
四、更新
1、Save() 保存多个字段
Save 会保存所有的字段,即使字段是零值
保存 是一个组合函数。 如果保存值不包含主键,它将执行 Create,否则它将执行 Update (包含所有字段)。
works := []Work{{User: User{Name: "张三", Age: 18}, Work: "程序员"},{User: User{Name: "李四", Age: 19}, Work: "程序员"},{User: User{Name: "王五", Age: 20}, Work: "程序员"},}result := db.Save(works)if result.Error != nil && result.RowsAffected == 0 {fmt.Println("保存失败")return}fmt.Println("保存成功")
2、更新单个字段
可以使用主键查询也可以是使用某个特定的字段查询,也可以同时使用查询。
// 根据表的name进行修改信息result := db.Model(&Work{}).Where("name=?", "张三").Updates(map[string]interface{}{"age": 112, "work": "大佬"})if result.Error != nil {panic(result.Error)}if result.RowsAffected == 0 {panic("没有更新数据")}fmt.Println(result.RowsAffected)// 根据id修改信息var w Workw.ID = 1result = db.Model(&w).Updates(map[string]interface{}{"age": 32, "work": "行长"})if result.Error != nil {panic(result.Error)}if result.RowsAffected == 0 {panic("没有更新数据")}fmt.Println(result.RowsAffected)
五、删除
如果你的模型包含了 gorm.DeletedAt字段(该字段也被包含在gorm.Model中),那么该模型将会自动获得软删除的能力!
当调用Delete时,GORM并不会从数据库中删除该记录,而是将该记录的DeleteAt设置为当前时间,而后的一般查询方法将无法查找到此条记录。
软删除:
// 根据主键删除var w Workw.ID = 7// db.Delete(&Work{}, 8) //一样的result := db.Where("age < ?", 98).Delete(&w)if result.Error != nil {panic(result.Error)}if result.RowsAffected == 0 {panic("没有删除任何数据")}fmt.Println(result.RowsAffected)
物理删除:
// 物理删除主键为 5 6的两条信息
db.Unscoped().Delete(&Work{}, 5, 6)