更新
更新的前提是先查询到记录
Save保存所有字段
用于单个记录的全字段更新
它会保存所有字段,即零值也会保存
var P Person
DB.Take(&P)
P.Age = 23
//全字段更新
DB.Save(&P)
更新指定字段
可以使用select选择要更新的字段
var p Person
DB.Take(&p)
p.Age = 21
//全字段更新
DB.Select("age").Save(&p)
批量更新
例如我想给年龄21的学生,都更新以下邮箱
var PList []Person
DB.Find(&PList,"age = ?",21).Update("email","is21@qq.com")
还要一种更简单的方式
DB.Model(&PList{}).Where("age = ?",21).Update("email","is@qq.com")
这样的更新方式也是可以更新零值的
更新多列
如果是结构体,它默认不会更新零值
email:="xxx@gmail.com"
DB.Model(&Person{}).Where("age = ?",21),Update(Person{
Email:&email,
Gender:false,//这个不会更新
})
如果想让他更新零值,用select就好
email:="xxx@qq.com"
DB.Model(&Person{}).Where("age = ?",21).Select("gender","email").Update(Person{
Email:&email,
Gender:false,
})
如果不想多写几行代码,推荐使用map
DB.Model(&Person{}).Where("age = ?",21).Update(map[string]any{
"email":&email,
"gender":false
})
更新选定字段
Select选定字段 Omit忽略字段
删除
根据结构体删除
db.Delete(&p)
删除多个
db.Delete(&p{},[]int{1,2,3})
db.Delete(&p)
4.创建HOOK
在创建一条记录到数据库的时候,我希望做点事情
type Person struct{
ID uint `gorm:"size:3"`
Name string `gorm:"size:8"`
Age int `gorm:"size:3"`
Gender bool
Email *string `gorm:"size:32"`
}
func (user *Person) BeforeCreate(tx *gorm.DB) (err error){
email:=fmt.Sprintf("%s@qq.com",user.Name)
user.Email = &email
return nil
}
5.高级查询
创建表格信息
type PersonName struct {
ID uint `gorm:"size:3"`
Name string `gorm:"size:8"`
Age int `gorm:"size:3"`
Gender bool
Email *string `gorm:"size:32"`
}
var Plist []PersonName
DB.Find(&Plist).Delete(&Plist)
Plist = []PersonName{
{1, "小明", 32, true, PtrString("xm@xm.com")},
{2, "小刘", 33, true, PtrString("xl@xl.com")},
{3, "小红", 34, false, PtrString("xh@xh.com")},
}
DB.Create(&Plist)
Where
//查询姓名为小明的
DB.Where("name = ?", "小明").Find(&Plist)
fmt.Println(Plist)
// //查询姓名不等于小明的
DB.Where("name <> ?", "小明")
fmt.Println(Plist)
// //查询姓名为小明和小刘的
DB.Where("name in ?", []string{"小明", "小刘"}).Find(&Plist)
fmt.Println(Plist)
// //查询姓名为小xx的
DB.Where("name like ?", "小%").Find(&Plist)
fmt.Println(Plist)
// //查询年龄大于23的 邮箱为xx@xm.com的
DB.Where("age > ? ane email like ?", "23", "%@xm.com").Find(&Plist)
fmt.Println(Plist)
// //查询性别为女的 邮箱为xx@xh.com的
DB.Where("gender = ? or email like ?", false, "%@xh.com").Find(&Plist)
fmt.Println(Plist)
使用结构体查询
//会过滤零值
DB.Where(&Person{Name:"小明",Age:33}).Find(&Plist)
fmt.Println(Plist)
使用map查询
不会过滤零值
DB.Where(map[string]any{"name": "小刘", "age": 33}).Find(&Plist)
fmt.Println(Plist)
Not条件
和Where中的not等价
DB.Not("age > 23").Find(&Plist)
fmt.Println(Plist)
Or条件
和Where中的or等价
DB.Or("gender = ?",false).Or("email like ?","xx@xm.com").Find(&Plist)
Select选择字段
DB.Select("name","age").Find(&Plist)
fmt.Println(Plist)
//没有被选中,会被赋零值
可以使用扫描Scan,讲选择的字段存入另一个结构体中
type User struct{
Name string
Age int
}
var persons []Person
var users []User
DB.Select("name","age").Find(&persons).Scan(&users)
fmt.Println(users)
这样写也是可以的,不过最终会查询两次,还是不这样写
SELECT `name`,`ago` FROM `students`
SELECT `name`,`ago` FROM `students`
这样写就只查询一次了
type User struct{
Name string
Age int
}
var persons []Person
var users []User
DB.Model("name","age").Find(&persons).Scan(&users)
fmt.Println(users)
还可以这样
var users []User
DB.Table("persons"),Select("name","ago"),Scan(&Plist)
fmt.Println(users)
Scan是根据column列名进行扫描的