zoukankan      html  css  js  c++  java
  • go语言:GORM

    7.GORM

    • 对象关系映射。

      数据表  -> 结构体
      数据行  -> 结构体实例
      字段   -> 结构体字段
      
    • 优点:提高开发效率,缺点牺牲执行性能,灵活性,弱化SQL能力。

    • gorm下载: 官网

    go get -u github.com/jinzhu/gorm
    

    7.1数据库的连接

    // 引包
    import (
    	 _ "github.com/jinzhu/gorm/dialects/mysql"
    	"github.com/jinzhu/gorm"
    )
    // 结构体创建
    type UserInfo struct {
    	Id uint
    	Name string
    	Gender string
    	Hobby string
    }
    
    • 连接数据库
    // 连接数据库 这里指定编码格式,可解析时间类型,时间取当地时间
    	db, err :=gorm.Open("mysql", "root:123@(ip:3306)/db1?charset=utf8mb4&parseTime=True&loc=Local")
    	if err != nil{
    		panic(err)
    	}
    // 关闭连接
    	defer db.Close()
    

    7.2数据库迁移和最简单CURD

    • 创建表 自动迁移。让结构体和数据表形成对应关系
    db.AutoMigrate(&UserInfo{})
    
    • 插入一条数据
    / 创建数据行
    	user1 := UserInfo{1,"jk","man","篮球"}
    	db.Create(&user1)
    
    • 查询第一条数据
    var u UserInfo
    db.First(&u)
    fmt.Println(u)
    
    • 更新一条数据
    var u UserInfo
    // 查询到第一条数据,然后更新
    db.First(&u)
    db.Model(&u).Update("hobby","running")
    
    • 删除操作
    db.Delete(&u)
    

    7.3 GORM模型定义

    • GORM 内置一个gorm.Model结构体,gorm.Model是一个包含了ID,CreteAt,UpdateAt,DeleteAt四个字端的Golang结构体。
    type Model struct {
      ID uint `gorm:"primary_key"`
      CreateAt time.Time
      UpdateAt time.Time
      DeleteAt *time.Time
    }
    
    • 你可以自行将它嵌入到你自己模型中:
    type User struct {
    	gorm.Model
      Name string
    }
    
    • 模型定义示例
    type User struct{
    	gorm.Model// 内嵌Model
    	Name string
    	Age sql.NullInt64//零值类型
    	Birthday *time.Time
    	Email string `gorm:"type:varchar(100);unique_index"`
    	Role string `gorm:"size:255"`// 设置字端大小255
    	MemberNumber string `gorm:"unique;not null"`// 设置会员号,唯一且不为空
    	Num int `gorm:"AUTO_INCREMENT"`//设置num为自增类型
    	Address string `gorm:"index:addr"`// 给address设置索引为addr
    	IgnoreMe int `gorm:"-"`//忽略本字端
    }
    
    • 自定义字段为主键
    type Animal struct {
      AnimalID int64 `gorm:"primary_key"`
      Name string
    }
    
    • 表的名字默认是结构体复数,你也可以自定义表的名字
    type Animal struct {
    	AnimalID int64 `gorm:"primary_key"`
    	Name string
    }
    
    // 自定义表名字,因唯一指定表名,不会受方法影响
    func (Animal) TableName() string{
    	return "self_animal"
    }
    
    • 禁用表的复数形式
    db.SingularTable(true)
    
    • 强行指定表名
    // 使User结构体创建名叫 mysql_self_name表
    db.Table("mysql_self_name").CreateTable(&User{})
    
    • 通过自定义方法设计表名
    gorm.DefaultTableNameHandle = func (db *gorm.DB, defaultTableName string) string{
      return "SMS_" + defaultTableName
    }
    // 给创建的默认表名,加前缀SMS
    
    • 自定义列的名称
    type User struct {
      Age sql.NullInt64 `gorm:"column:user_age"`
    }
    // 会新增一个user_age字端。
    
    • 时间类型

      CreatedAt

    db.Create(&user)
    db.Model(&user).Update("CreatedAt", time.Now())
    

    ​ UpdatedAt

    db.Save(&user)
    db.Model(&user).Update("name","xjk")
    

    ​ DeletedAt

    • 调用删除记录,将会设置DeletedAt字端为当前时间,而不是直接将记录从数据库中删除。

    7.4 GORM 的CURD

    • 首先定义一个模型
    type uGroup struct {
    	Id int64
    	Name string `gorm:"defalut:'wang'"`
    	Age int64
    }
    

    7.4.1创建记录

    • NewRecord
    var u = type uGroup struct {
    	Id int64
    	Name string `gorm:"defalut:'wang'"`
    	Age int64
    }{Name:"laobing2", Age:77}
    pk := db.NewRecord(&u)
    fmt.Println(pk)// true
    // NewRecord 查询当主键为空返回true
    
    // 创建用户
    db.Create(&u)
    pk2 := db.NewRecord(u)
    // 此时用户已创建,已经有主键
    fmt.Println(pk2)// false
    

    7.4.2 默认值

    • 通过tag定义字段的默认值。
    type uGroup struct {
       Id int64
       Name string `gorm:"default:'ss'"`
       Age int64
    }
    
    • 值得注意是,在创建记录生成SQL语句会排除没有值或值为零的字段。在将记录插入到数据库后,Gorm会从数据库加载到那些字端默认值。
    var u = uGroup{Name:"",Age:99}
    db.Create(&u)
    
    • 所有字段零值,如: 0 "" false 或者其他零值。都不会保存到数据库中,但会使用他们默认值。若果想要避免此情况,可以考虑使用指针.
    • 方式1:指针方式实现
    type uGroup struct {
    	Id int64
    	Name *string `gorm:"default:'ss'"`
    	Age int64
    }
    var u = uGroup{Name:new(string), Age:77}
    db.Create(&u)
    
    • 方式2:Scanner/Valuer接口方式
    type uGroup struct {
    	Id int64
    	Name sql.NullString `gorm:"default:'ss'"`
    	Age int64
    }
    var u = uGroup{Name:sql.NullString{"", true}, Age:55}
    db.Create(&u)
    

    7.4.3普通查询

    • 一般查询
    var u uGroup
    // 根据主键查询
    db.First(&u)
    // 获取第一条记录
    db.Take(&u)
    // 根据主键查询最后一条记录
    db.Last(&u)
    // 查询所有记录
    var us []uGroup
    db.Find(&us)
    // 查询主键id=3记录
    var u uGroup
    db.First(&u, 3)
    

    7.4.4 Where查

    • 普通SQL查询
    var u uGroup
    // 查询name=ss 的第一条记录
    db.Where("name=?","ss").First(&u)
    // 查询 所有满足name=ss的记录
    var us []uGroup
    db.Where("name=?","ss").Find(&us)
    // 查询 name <>
    db.Where("name <> ?","ss").Find(&us)
    // IN 查询
    db.Where("name IN (?)", []string{"ss","jj"}).Find(&us)
    // LIKE
    db.Where("name LIKE ?","%ss%").Find(&us)
    // AND
    db.Where("name = ? AND age >= ?", "ss", "25").Find(&us)
    // 时间Time
    db.Where("updated_at > ?", lastWeek).Find(&us)
    db.Where("created_at BETWEEN ? AND ?",last, yest).Find(&us)
    

    7.4.5 struct & Map查询

    • Struct demo
    var u uGroup
    // 查询name=ss,age=20
    db.Where(&uGroup{Name:"ss",Age:20}).First(&u)
    
    • Map查询
    // Map查询
    var us []uGroup
    db.Where(map[string]interface{}{"name":"ss","age":77}).Find(&us)
    // SELECT * FROM u_groups WHERE name = "ss" AND age = 77;
    
    • 主键的切片
    db.Where([]int64{1,2,5}).Find(&us)
    // SELECT * FROM u_groups WHERE id IN (1, 2, 5)
    
    • 当通过结构体进行查询时,GORM将会只通过非零值字段查询。这意味着如果你的字段值为0,"",false或者其他零值时,将不会被用于构建查询条件。
    db.Where(&User{name:"ss",Age:0}).Find(&us)
    
    • 不过你可以通过上面提到2个方法。通过指针或是Scanner/Valuer

    7.4.6Not条件查询

    db.Not("name","ss").First(&u)
    // SELECT * FROM u_groups WHERE name <> "ss" LIMIT 1
    
    // Not In
    db.Not("name", []string{"ss","1234"}).Find(&us)
    
    // 主键不在切片中
    db.Not([]int64{1,2,3}).First(&u)
    
    // 查询第一个
    db.Not([]int64{}).First(&u)
    // Struct
    db.Not(uGroup{Name:"xx"}).First(&u)
    

    7.4.7 Or条件查询

    db.Where("name=?","ss").Or("age=?","43").Find(&us)
    //SELECT * FROM u_groups WHERE name = 'ss' OR age = 43;
    // Struct
    db.Where("name='jk'").Or(uGroup{Name:"ming"}).Find(&us)
    // Map
    db.Where("name='jk'").Or(map[string]interface{}{"name":"ming"}).Find(&us)
    //SELECT * FROM u_groups WHERE name = 'ss' OR name = 'ming';
    

    7.4.8内联条件

    • 作用与Where查询类似,当内联条件与多个立即执行方法一起使用时,内联条件不会传递给后面立即执行。
    db.First(&u,5)//适用整形
    db.First(&u,"id=?","string_primary_key")//适用菲整形主键
    db.Find(&u,"name <> ? AND age > ?","jk", 20)
    // struct
    db.Find(&us,uGroup{Age:20})
    // SELECT * FROM u_groups WHERE age=20;
    
    // Map
    db.Find(&u,map[string]interface{}{"age":20})
    // SELECT * FROM u_groups WHERE age=20;
    

    7.4.9额外查询选项

    • 为查询SQL添加额外的SQL操作
    db.Set("gorm:query_option","FOR UPDATE").First(&u,5)
    // SELECT * FROM u_groups WHERE id=5 FOR UPDATE;
    

    7.4.10FirstOrInit

    • 获取匹配的第一条记录,否则根据给定的条件初始化一个新的对象(仅支持struct 和 map 条件)
    // 当没有找到
    db.FirstOrInit(&u, uGroup{Name:"not exist"})
    fmt.Println(u)//返回结果:{0 not exist 0}
    // 当找到了
    db.Where(uGroup{Name: "ss"}).FirstOrInit(&u)
    fmt.Println(u)//返回结果: {1 ss 77}
    
    // 通过map获取
    db.FirstOrInit(&u,map[string]interface{}{"name":"ss"})
    
    • Attrs
      • 如果记录未找到,将使用参数初始化struct
    // 1.未找到:
    db.Where(uGroup{Name:"not exist"}).Attrs(uGroup{Age:22}).FirstOrInit(&u)
    fmt.Println(u)// {0 not exist 22}
    // 当你查询用户名: not exist不存在时候会 默认返回User{Name: "not exist", Age: 20}
    
    // 当然你也可以这么写
    db.Where(uGroup{Name:"not exist"}).Attrs("age", 20).FirstOrInit(&u)
    
    // 2.找到了
    相同写法。
    
    • Assign
      • 无论是否查询到,都将参数赋值给struct
    // 未找到
    db.Where(uGroup{Name:"not exist"}).Assign(uGroup{Age:22}).FirstOrInit(&u)
    fmt.Println(u)// {0 not exist 22}
    // 找到
    db.Where(uGroup{Name:"ss"}).Assign(uGroup{Age:77}).FirstOrInit(&u)
    fmt.Println(u)// {1 ss 77}
    

    7.4.11FirstOrCreate

    • 获取匹配的第一条记录,否则根据给定的条件创建一个新的记录(仅支持struct和map条件)
    // 未找到
    db.FirstOrCreate(&u, uGroup{Name:"not exist"})
    fmt.Println(u)// 没有找到,直接创建了:{15 not exist 0}
    // 找到
    db.Where(uGroup{Name: "ss"}).FirstOrCreate(&u)
    fmt.Println(u)//{1 ss 77}
    
    • Attrs
      • 如果记录未找到,将使用参数创建struct 和记录
    db.Where(uGroup{Name:"Tom"}).Attrs(uGroup{Age:20}).FirstOrCreate(&u)
    fmt.Println(u) //未找到会创建: {16 Tom 20},找到了会返回结果
    
    • Assign
      • 不管记录是否找到,豆浆参数赋值给struct并保存数据库
    db.Where(uGroup{Name:"Lucy"}).Assign(uGroup{Age:30}).FirstOrCreate(&u)
    fmt.Println(u) // 未找到创建:{17 Lucy 30}
    
    db.Where(uGroup{Name:"Lucy"}).Assign(uGroup{Age:32}).FirstOrCreate(&u)// 找到了,更改用户信息,age改为32
    

    7.5GORM高级查询

    7.5.1子查询

    • 通过*gorm.expr的子查询
    type Order struct {
    	DeletedAt interface{}
    	State string
    	Amount int
    }
    var orders Order
    	// SELECT * FROM "orders"  WHERE "orders"."deleted_at" IS NULL AND (amount > (SELECT AVG(amount) FROM "orders"  WHERE (state = 'paid')));
    db.Where("amount > ?",db.Table("orders").Select("AVG(amount)").Where("state = ?","sk2").SubQuery()).Find(&orders)
    	fmt.Println(rest)
    fmt.Println(orders)
    

    7.5.2选择字段

    • Select 指定你想从数据库中检索的字段,默认会选择全部字段
    var userinfo []uGroup
    // 方式1
    db.Select("name,age").Find(&userinfo)
    fmt.Println(userinfo)
    //// SELECT name, age FROM users;
    // 方式2
    db.Select([]string{"name","age"}).Find(&userinfo)
    fmt.Println(userinfo)
    // 方式3
    db.Table("users").Select("COALESCE(age,?)", 42).Rows()
    //// SELECT COALESCE(age,'42') FROM users;
    

    7.5.3排序

    • Order 指定从数据库中检索出记录顺序。设置第二个参数reorder为true ,可以覆盖前面定义的排序条件。
    var users []uGroup
    db.Order("age desc,name").Find(&users)
    fmt.Println(users)
    // SELECT * FROM u_group order by age desc,name
    
    // 多字段排序
    db.Order("age desc").Order("name").Find(&users)
    fmt.Println(users)
    / SELECT * FROM users ORDER BY age desc, name;
    
    // 覆盖排序
    db.Order("age desc").Find(&users1).Order("age", true).Find(&users2)
    //// SELECT * FROM users ORDER BY age desc; (users1)
    //// SELECT * FROM users ORDER BY age; (users2)
    

    7.5.4数量

    • limit 指定数据库检索的最大记录数。
    var users []uGroup
    db.Limit(2).Find(&users)
    fmt.Println(users)
    // SELECT * FROM users LIMIT 3;
    
    // -1 取消Limit条件
    db.Limit(10).Find(&users1).Limit(-1).Find(&users2)
    //// SELECT * FROM users LIMIT 10; (users1)
    //// SELECT * FROM users; (users2)
    

    7.5.5偏移

    • Offset,指定开始返回记录前要跳过的记录数。
    var users []uGroup
    db.Limit(2).Offset(1).Find(&users)
    fmt.Println(users)
    // SELECT * FROM u_groups limit 3 offset 1;
    

    7.5.6统计总数

    var users []uGroup
    var count int
    db.Where("name = ?", "xiaoming2").Or("name = ?","xiaoming3").Find(&users).Count(&count)
    fmt.Println(users,count)
    // [{2 xiaoming2 13} {3 xiaoming3 23}] 2
    
    
    db.Model(&uGroup{}).Where("name = ?","xiaoming2").Count(&count)
    fmt.Println(count)
    // SELECT count(*) FROM users WHERE name = "xiaoming2"
    
    db.Table("u_groups").Count(&count)
    // SELECT count(*) FROM u_groups;
    
    db.Table("u_groups").Select("count(distinct(name))").Count(&count)
    //// SELECT count( distinct(name) ) FROM u_groups;
    
    • 注意:Count 必须是链式查询的最后一个操作,因为它会覆盖前面SELECT,但如果里面使用count时就不会覆盖。

    7.5.7Group & Having

    • 示例1:
    type Result struct{
    	State string
    	Total int
    }
    
    rows, err := db.Table("orders").Select("state,sum(amount) as total").Group("state").Rows()
    	for rows.Next() {
    		r := &Result{}
    		err = db.ScanRows(rows,r)
    		fmt.Println(r)
    		if err != nil{
    			fmt.Println(err)
    			break
    		}
    	}
    
    • 示例2:
    var res []Result
    db.Table("orders").Select("state,sum(amount) as total").Group("state").Scan(&res)
    fmt.Println(res)
    
    • 示例三
    // Having
    rows, err := db.Table("orders").Select("state,sum(amount) as total").Group("state").Having("sum(amount) > ?",30).Rows()
    	if err != nil{
    		fmt.Println(err)
    	}
    	for rows.Next() {
    		r := &Result{}
    		err = db.ScanRows(rows,r)
    		if err != nil {
    			fmt.Println(err)
    			break
    		}
    		fmt.Println(*r)
    	}
    
    • 示例四:
    var res []Result
    db.Table("orders").Select("state,sum(amount) as total").Group("state").Having("sum(amount) > ?",30).Scan(&res)
    fmt.Println(res)
    

    7.5.8连接

    • 通过Join进行连接。
    type uGroup struct {
    	Id int64
    	Name string `gorm:"default:'ss'"`
    	Age int64
    }
    type Email struct {
    	Id int64
    	Email string
    	UserId int64
    }
    type Result2 struct {
    		Uname string
    		Ename string
    }
    
    	rows, err := db.Table("u_groups").Select("u_groups.name as uname, emails.email as ename").Joins("left join emails on emails.id = u_groups.id").Rows()
    	for rows.Next(){
    		r := &Result2{}
    		err = db.ScanRows(rows,r)
    		if err != nil{
    			fmt.Println(err)
    			break
    		}
    		fmt.Println(*r)
    	}
    
    • 示例2:
    type Result2 struct {
    		Uname string
    		Ename string
    	}
    var results []Result2
    db.Table("u_groups").Select("u_groups.name as uname, emails.email as ename").Joins("right join emails on emails.id = u_groups.id").Scan(&results)
    fmt.Println(results)
    
    • 示例3:
    var u uGroup
    db.Joins("JOIN emails ON emails.id = u_groups.id AND emails.email = ?", "235102030@qq.com").Joins("JOIN credit_cards ON credit_cards.id=u_groups.id").Where("credit_cards.common=?","common1").Find(&u)
    fmt.Println(u)
    

    7.5.9Pluck

    • Pluck 查询model中的一个列作为切片,如果想要查询多个列可以收纳柜Scan
    var ages []int64
    var users []uGroup
    db.Find(&users).Pluck("age",&ages)
    fmt.Println(ages)
    
    • Model指定表Struct
    var names []string
    db.Model(&uGroup{}).Pluck("name",&names)
    fmt.Println(names)
    
    • 查找多个列
    db.Select("name,age").Find(&users)
    fmt.Println(users)
    

    7.5.10扫描

    • Scan扫描结果至一个struct
    type Result struct {
    		Name string
    		Age int
    	}
    var result Result
    db.Table("u_groups").Select("name,age").Where("name=?","xiaoming").Scan(&result)
    fmt.Println(result)
    
    • 示例2
    var results []Result
    db.Table("u_groups").Select("name,age").Where("id > ?",0).Scan(&results)
    fmt.Println(results)
    
    • 示例3:
    //原生SQL
    db.Raw("SELECT name,age from u_groups WHERE name=?","xiaoming").Scan(&results)
    fmt.Println(results)
    

    7.5.11 链式操作相关

    • 链式操作,Gorm实现了链式操作接口,所以你可以把代码写成这样。
    var results []Result
    	tx := db.Where("name = ?","xiaoming")
    	// 添加更多条件
    	judge:=true
    	if judge {
    		tx = tx.Where("age > ?",5)
    	} else {
    		tx = tx.Where("age = ?",30)
    	}
    	tx.Find(&results)
    	fmt.Println(results)
    
    • 在调用立即执行方法前不能生成Query语句,借助这个特性你可以i创建一个函数处理一些普通逻辑。

    7.5.12范围

    • Scopes,Scopes 是建立在链式操作的基础之上。基于它,你可以抽取一些通用逻辑,写出更多可重用的函数库。
    func UGroupAge20(db *gorm.DB) *gorm.DB{
    	return db.Where("age > ?", 20)
    }
    
    func NameeqXiaoming(db *gorm.DB) *gorm.DB{
    	return db.Where("name = ?","xiaoming")
    }
    func UGroupIdeq1(db *gorm.DB) *gorm.DB{
    	return db.Where("id = ?", 1)
    }
    
    func uGroupInId(ids []int) func(db *gorm.DB) *gorm.DB{
    	return func(db *gorm.DB) *gorm.DB {
    		return db.Scopes(UGroupAge20).Where("id IN (?)",ids)
    	}
    }
    var us []uGroup
    
    db.Scopes(UGroupAge20,NameeqXiaoming,UGroupIdeq1).Find(&us)
    fmt.Println(us)
    db.Scopes(uGroupInId([]int{1,2})).Find(&us)
    fmt.Println(us)
    

    7.5.13多个立即执行

    • 在GORM中使用多个立即执行方法时,后一个立即执行方法会服用前一个立即执行方法的条件(不包含内联条件)
    var users []uGroup
    var count int64
    db.Where("name Like ?", "xiaoming%").Find(&users,"id IN (?)", []int{1,2,3}).Count(&count)
    fmt.Println(users)
    fmt.Println(count)
    

    7.6 更新

    7.6.1更新所有字段

    • 使用Save() 默认会更新所有字段,即使你没有去赋值。
    var user uGroup
    	db.First(&user)
    	fmt.Println(user)
    	user.Name = "jk"
    	user.Age = 22
    	db.Save(&user)
    

    7.6.2 更新修改字段

    • 使用Update或者Updates更新指定字段
    // 更新单个属性,如果它有变化
    db.Model(&user).Update("name","hello")
    // 根据条件更新单个属性
    db.Model(&user).Where("age = ?",21).Update("name","jk")
    // 使用map更新多个属性,只会更新其中有变化属性
    db.Model(&user).Updates(map[string]interface{}{"name":"xujunkai","age":18})
    // 使用struct 更新多个属性,只会更新其中变化且非零的字段
    db.Model(&user).Updates(uGroup{Name:"xjk",Age: 20})
    // struct更新时,GORM只会更新那些非零值的字段。
    // 对于 "" 0 false 不会发生任何更新
    db.Model(&user).Updates(uGroup{Name:"",Age: 0})
    

    7.6.3 更新选定字段

    • 如果你想更新或忽略某些字段,你可以使用Select,Omit
    // 下面我们在map中更新name,age.但是我们只选择了name.所以只更新name
    db.Model(&user).Select("name").Updates(map[string]interface{}{"name":"xujunkai","age":19})
    
    
    // Omit 表示要忽略字段
    db.Model(&user).Omit("name").Updates(map[string]interface{}{"name":"xiaoming","age":30})
    

    7.6.4无Hooks更新

    • 上面更新操作会自动运行Model的。BeforeUpdate,AfterUpdate方法。更新UpdateAt时间戳。更新时保存其Associations.如果你想调用这些方法,你可以使用UPdateColume,UpdateColumns
    db.First(&user)
    db.Model(&user).UpdateColumn("name","hello")
    // 更新多个属性。类似Updates
    db.Model(&user).UpdateColums(User{Name:"hello",Age:18})
    

    7.6.5批量更新

    • 批量更新时,Hook(钩子函数)。不会更新。
    // map方式批量更新
    db.Table("u_groups").Where("id IN (?)",[]int{1,5,11}).Updates(map[string]interface{}{"name":"xjk","age":33})
    
    // struct 批量更新 只会更新非零字段。如果想更新所有字段。请使用map
    db.Model(uGroup{}).Updates(uGroup{Name:"xiaoming",Age: 15})
    
    // RowsAffected 获取更新记录
    res := db.Model(uGroup{}).Updates(uGroup{Name: "xjk",Age: 40}).RowsAffected
    fmt.Println(res)
    

    7.6.6使用SQL表达式

    • 查询表中第一条数据,然后更新
    ar user uGroup
    db.First(&user)
    
    
    db.Model(&user).Update("age",gorm.Expr("age*?+?",4,1))
    // UPDATE `u_groups` SET `age` = age * 4 + 1, `updated_at` = '2020-08-01 13:10:20'  WHERE `users`.`id` = 1;
    
    db.Model(&user).Updates(map[string]interface{}{"age":gorm.Expr("age - ?",500)})
    
    db.Model(&user).Where("age > 10").UpdateColumn("age",gorm.Expr("age - ?",5))
    

    7.6.7其他更新选项

    // 为 update SQL添加其他SQL
    db.Model(&user).Set("gorm:update_option","OPTION (OPTIMIZE FOR UNKNOWN)").Update("name","hello")
    

    7.7删除

    7.7.1删除记录

    • 警告 删除记录时,请确保主键字段有值。GORM会通过主键去删除记录,如果主键为空,GORM会删除该model所有记录.
    var user uGroup
    db.First(&user)
    db.Delete(&user)
    

    7.7.2批量删除

    • 删除全部匹配记录
    db.Where("email LIKE ?","%xjk%").Delete(uGroup{})
    

    7.7.3软删除

    • 如果一个model有,DeletedAt字段,他将自动获得软删除功能,当调用Delete方法时,记录不会真正的从数据库中被删除,只会DeletedAt字段值会被设置为当前时间
    db.Delete(&user)
    
    // 批量删除
    db.Where("age = ?",20).Delete(&u_Group{})
    
    // 查询会忽略被软删除的记录
    db.Where("age = ?",84).Find(&user)
    
    // 通过Unscoped方法可以查询被软删除的记录
    var users []uGroup
    db.Unscoped().Where("age=?",84).Find(&users)
    fmt.Println(users)
    

    7.7.4物理删除

    db.Unscoped().Delete(&user)
    
  • 相关阅读:
    new一个对象的时候,实际做了些什么
    ES6 class——getter setter音乐播放器
    vue中引入公用过滤器?
    this详解下
    012天this详解上
    011天之跨域资源共享CORS
    010天JSON.stringify()详解
    009天之跨浏览器的事件处理程序
    使用XHR上传文件要不要了解一下?
    简单化最小化语句数
  • 原文地址:https://www.cnblogs.com/xujunkai/p/13416904.html
Copyright © 2011-2022 走看看