Golang学习笔记之GORM基础使用(二)
本文章主要学习GORM的增删查改。若还没有完成数据库和数据表的创建、定义模型以及数据库的连接请先学习本本专栏文章Golang学习笔记之GORM基础使用(一)。本文为学习笔记,通过GORM官方中文文档和李文周的博客学习整理而成。
也可以使用原生sql语句。当然使用orm语句的便利点在于切换,可以切换不同的数据库。
目录
创建记录
基本操作
默认值
查询操作
基本查询
条件查询Where
结构体和Map查询
查询零值条件
NOT条件
Or条件
内联条件
额外查询选项
FirstOrInit
Attrs(找不到时使用)
Assign(不管找不找到都是用)
FirstOrCreate
Attrs(找不到时使用)
Assign(不管找不找到都是用)
检索相应字段
排序
数量
偏移
总数
更新操作
保存所有字段
更新单个列
更新多列
更新选定字段
更新 Hook
无Hooks更新
批量更新
删除操作
基本删除
根据主键删除
Delete Hook
批量删除
阻止全局删除
软删除
查找被软删除的记录
创建记录
官方文档创建链接:
创建 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.https://gorm.io/zh_CN/docs/create.html小技巧:在学习过程中要是有不理解的步骤可以通过Debug()(例如db.Debug().Create(&User))可以打印出对应的sql语句更好理解。
基本操作
1、先在代码层面创建一个User对象,此时数据中是没有这一条数据的。
2、使用db.Create()进行创建。注意在括号中要使用指针。
user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()} //在代码层面创建一个User对象result := db.Create(&user) // 通过数据的指针来创建user.ID // 返回插入数据的主键
result.Error // 返回 error
result.RowsAffected // 返回插入记录的条数
3、可以使用下述代码判断主键是否为空。通过返回值可以判断如果主键为空可以直接创建,若不为空说明该条数据已经存在,可以选择更改数据或者不做更改。
db.NewRecord(&user)
默认值
在用户不传递这个值的时候就使用默认值进行代替。也就是所有字段的零值,比如0
, ""
,false
或者其它零值
,都不会保存到数据库内,但会使用他们的默认值。
`gorm:"default:'xka'"`
放在代码中如下位置:
// UserInfo 用户信息
type UserInfo struct { ID uint Name string `gorm:"default:'xka'"` //在name字段为空时,使用xka代替Gender stringHobby string
}//表示配置操作数据库的表名称,如果没有表名则是直接使用结构体的复数
func (UserInfo) TableName() string {return "userinfo"
}
注意:通过tag定义字段的默认值,在创建记录时候生成的 SQL 语句会排除没有值或值为 零值 的字段。 在将记录插入到数据库后,Gorm会从数据库加载那些字段的默认值。
若是设置了默认值之后想要保留空字符串时,可以考虑使用指针或实现 Scanner/Valuer
接口。
1、使用指针方式
// 使用指针
type UserInfo struct { ID uint Name *string `gorm:"default:'xka'"` //使用的是字符串的指针*stringGender stringHobby string
}user := User{Name: new(string), Age: 18))} //new(string)空字符串的指针
db.Create(&user) // 此时数据库中该条记录name字段的值就是''
2、使用实现 Scanner/Valuer
接口
type UserInfo struct { ID uint Name sql.NullString `gorm:"default:'xka'"` // sql.NullString 实现了Scanner/Valuer接口Gender stringHobby string
}user := User{Name: sql.NullString{"", true}, Age:18}
db.Create(&user) // 此时数据库中该条记录name字段的值就是''
查询操作
官方文档查询链接:
查询 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.https://gorm.io/zh_CN/docs/query.html GORM 提供了 First
、Take
、Last
方法,以便从数据库中检索单个对象。当查询数据库时它添加了 LIMIT 1
条件,且没有找到记录时,它会返回 ErrRecordNotFound
错误
基本查询
注意:以下几种要以id作为主键。
var user User
var users []User// 获取第一条记录(主键升序)
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;// 查询所有的记录
db.Find(&users)SELECT * FROM users;// 查询指定的某条记录(仅当主键为整型时可用)
db.First(&user, 10)SELECT * FROM users WHERE id = 10;result := db.First(&user)
result.RowsAffected // 返回找到的记录数
result.Error // returns error or nil// 检查 ErrRecordNotFound 错误
errors.Is(result.Error, gorm.ErrRecordNotFound)
条件查询Where
// Get first matched record
db.Where("name = ?", "xka").First(&user)SELECT * FROM users WHERE name = 'xka' limit 1;// Get all matched records
db.Where("name = ?", "xka").Find(&users)SELECT * FROM users WHERE name = 'xka';// <>不等于
db.Where("name <> ?", "xka").Find(&users)SELECT * FROM users WHERE name <> 'xka';// IN在一个范围里面
db.Where("name IN (?)", []string{"xka", "xka2"}).Find(&users)SELECT * FROM users WHERE name in ('xka','xka2');// LIKE模糊查询
db.Where("name LIKE ?", "%xk%").Find(&users)SELECT * FROM users WHERE name LIKE '%xk%';// AND
db.Where("name = ? AND age >= ?", "xka", "22").Find(&users)SELECT * FROM users WHERE name = 'xka' AND age >= 22;// Time
db.Where("updated_at > ?", lastWeek).Find(&users)SELECT * FROM users WHERE updated_at > '2000-01-01 00:00:00';// BETWEEN
db.Where("created_at BETWEEN ? AND ?", lastWeek, today).Find(&users)SELECT * FROM users WHERE created_at BETWEEN '2000-01-01 00:00:00' AND '2000-01-08 00:00:00';
结构体和Map查询
// Struct
db.Where(&User{Name: "xka", Age: 20}).First(&user)SELECT * FROM users WHERE name = "xka" AND age = 20 LIMIT 1;// Map
db.Where(map[string]interface{}{"name": "xka", "age": 20}).Find(&users)SELECT * FROM users WHERE name = "xka" AND age = 20;// 主键的切片
db.Where([]int64{20, 21, 22}).Find(&users)SELECT * FROM users WHERE id IN (20, 21, 22);
注意:当通过结构体进行查询时,GORM将会只通过非零值字段查询,这意味着如果你的字段值为0
,''
,false
或者其他零值
时,将不会被用于构建查询条件。例如:
db.Where(&User{Name: "xka", Age: 0}).Find(&users)
// SELECT * FROM users WHERE name = "xka";
//age=0没有作为条件参与sql语句
查询零值条件
可以使用指针或实现Scanner/Valuer接口来避免这个问题。
1、使用指针
// 使用指针
type User struct {gorm.ModelName stringAge *int
}
2、使用Scanner/Valuer接口
// 使用 Scanner/Valuer
type User struct {gorm.ModelName stringAge sql.NullInt64 // sql.NullInt64 实现了 Scanner/Valuer 接口
}
NOT条件
作用与Where类似的情形如下:
db.Not("name", "jinzhu").First(&user)SELECT * FROM users WHERE name <> "jinzhu" LIMIT 1;// Not In
db.Not("name", []string{"jinzhu", "jinzhu 2"}).Find(&users)SELECT * FROM users WHERE name NOT IN ("jinzhu", "jinzhu 2");// Not In slice of primary keys
db.Not([]int64{1,2,3}).First(&user)SELECT * FROM users WHERE id NOT IN (1,2,3);db.Not([]int64{}).First(&user)SELECT * FROM users;// Plain SQL
db.Not("name = ?", "jinzhu").First(&user)SELECT * FROM users WHERE NOT(name = "jinzhu");// Struct
db.Not(User{Name: "jinzhu"}).First(&user)SELECT * FROM users WHERE name <> "jinzhu";
Or条件
db.Where("role = ?", "admin").Or("role = ?", "super_admin").Find(&users)SELECT * FROM users WHERE role = 'admin' OR role = 'super_admin';// Struct
db.Where("name = 'jinzhu'").Or(User{Name: "jinzhu 2"}).Find(&users)SELECT * FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2';// Map
db.Where("name = 'jinzhu'").Or(map[string]interface{}{"name": "jinzhu 2"}).Find(&users)SELECT * FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2';
内联条件
作用与Where
查询类似,当内联条件与多个立即执行方法一起使用时, 内联条件不会传递给后面的立即执行方法(解释见下)。
立即执行方法:Immediate methods ,立即执行方法是指那些会立即生成SQL
语句并发送到数据库的方法, 他们一般是CRUD
方法,比如:Create
, First
, Find
, Take
, Save
, Update
, Delete
, Scan
, Row
…
// 根据主键获取记录 (只适用于整形主键)
db.First(&user, 23)SELECT * FROM users WHERE id = 23 LIMIT 1;// 根据主键获取记录, 如果它是一个非整形主键
db.First(&user, "id = ?", "string_primary_key")SELECT * FROM users WHERE id = 'string_primary_key' LIMIT 1;// Plain SQL
db.Find(&user, "name = ?", "jinzhu")SELECT * FROM users WHERE name = "jinzhu";db.Find(&users, "name <> ? AND age > ?", "jinzhu", 20)SELECT * FROM users WHERE name <> "jinzhu" AND age > 20;// Struct
db.Find(&users, User{Age: 20})SELECT * FROM users WHERE age = 20;// Map
db.Find(&users, map[string]interface{}{"age": 20})SELECT * FROM users WHERE age = 20;
额外查询选项
// 为查询 SQL 添加额外的 SQL 操作
db.Set("gorm:query_option", "FOR UPDATE").First(&user, 10)SELECT * FROM users WHERE id = 10 FOR UPDATE;
注:for update是一种行级锁,又叫排它锁,一旦用户对某个行施加了行级加锁,则该用户可以查询也可以更新被加锁的数据行,其它用户只能查询但不能更新被加锁的数据行.
FirstOrInit
获取匹配的第一条记录,否则根据给定的条件初始化一个新的对象 (仅支持 struct 和 map 条件)
// 未找到
db.FirstOrInit(&user, User{Name: "non_existing"})user -> User{Name: "non_existing"}// 找到
db.Where(User{Name: "xka"}).FirstOrInit(&user)user -> User{Id: 111, Name: "xka", Age: 20}
db.FirstOrInit(&user, map[string]interface{}{"name": "xka"})user -> User{Id: 111, Name: "xka", Age: 20}
Attrs(找不到时使用)
如果记录未找到,将使用参数初始化 struct. 给新建的对象添加其他属性值。
// 未找到
db.Where(User{Name: "non_existing"}).Attrs(User{Age: 20}).FirstOrInit(&user)SELECT * FROM USERS WHERE name = 'non_existing';user -> User{Name: "non_existing", Age: 20}db.Where(User{Name: "non_existing"}).Attrs("age", 20).FirstOrInit(&user)SELECT * FROM USERS WHERE name = 'non_existing';user -> User{Name: "non_existing", Age: 20}// 找到
db.Where(User{Name: "xka"}).Attrs(User{Age: 30}).FirstOrInit(&user)SELECT * FROM USERS WHERE name = xka';user -> User{Id: 111, Name: "xka", Age: 20}
Assign(不管找不找到都是用)
不管记录是否找到,都将参数赋值给struct。
// 未找到
db.Where(User{Name: "non_existing"}).Assign(User{Age: 20}).FirstOrInit(&user)user -> User{Name: "non_existing", Age: 20}// 找到
db.Where(User{Name: "Jinzhu"}).Assign(User{Age: 30}).FirstOrInit(&user)SELECT * FROM USERS WHERE name = jinzhu';user -> User{Id: 111, Name: "Jinzhu", Age: 30}
FirstOrCreate
获取匹配的第一条记录, 否则根据给定的条件创建一个新的记录 (仅支持 struct 和 map 条件)
// 未找到
db.Where(User{Name: "non_existing"}).Attrs(User{Age: 20}).FirstOrCreate(&user)SELECT * FROM users WHERE name = 'non_existing';INSERT INTO "users" (name, age) VALUES ("non_existing", 20);user -> User{Id: 112, Name: "non_existing", Age: 20}// 找到
db.Where(User{Name: "jinzhu"}).Attrs(User{Age: 30}).FirstOrCreate(&user)SELECT * FROM users WHERE name = 'jinzhu';user -> User{Id: 111, Name: "jinzhu", Age: 20}
Attrs(找不到时使用)
如果记录未找到,将使用参数初始化 struct. 给新建的对象添加其他属性值。
// 未找到
db.Where(User{Name: "non_existing"}).Attrs(User{Age: 20}).FirstOrCreate(&user)SELECT * FROM users WHERE name = 'non_existing';INSERT INTO "users" (name, age) VALUES ("non_existing", 20);user -> User{Id: 112, Name: "non_existing", Age: 20}// 找到
db.Where(User{Name: "jinzhu"}).Attrs(User{Age: 30}).FirstOrCreate(&user)SELECT * FROM users WHERE name = 'jinzhu';user -> User{Id: 111, Name: "jinzhu", Age: 20}
Assign(不管找不找到都是用)
不管记录是否找到,都将参数赋值给struct。
// 未找到
db.Where(User{Name: "non_existing"}).Assign(User{Age: 20}).FirstOrCreate(&user)SELECT * FROM users WHERE name = 'non_existing';INSERT INTO "users" (name, age) VALUES ("non_existing", 20);user -> User{Id: 112, Name: "non_existing", Age: 20}// 找到
db.Where(User{Name: "xka"}).Assign(User{Age: 30}).FirstOrCreate(&user)SELECT * FROM users WHERE name = 'xka';UPDATE users SET age=30 WHERE id = 111;user -> User{Id: 111, Name: "xka", Age: 30}
检索相应字段
Select,指定你想从数据库中检索出的字段,默认会选择全部字段。
db.Select("name, age").Find(&users)SELECT name, age FROM users;db.Select([]string{"name", "age"}).Find(&users)SELECT name, age FROM users;db.Table("users").Select("COALESCE(age,?)", 42).Rows()SELECT COALESCE(age,'42') FROM users;
排序
db.Order("age desc, name").Find(&users)SELECT * FROM users ORDER BY age desc, name;// 多字段排序
db.Order("age desc").Order("name").Find(&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)
数量
db.Limit(3).Find(&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)
偏移
Offset,指定开始返回记录前要跳过的记录数。
db.Offset(3).Find(&users)SELECT * FROM users OFFSET 3;// -1 取消 Offset 条件
db.Offset(10).Find(&users1).Offset(-1).Find(&users2)SELECT * FROM users OFFSET 10; (users1)SELECT * FROM users; (users2)
总数
Count,该 model 能获取的记录总数。
db.Where("name = ?", "xka").Or("name = ?", "xka2").Find(&users).Count(&count)SELECT * from USERS WHERE name = 'xka' OR name = 'xka2'; (users)SELECT count(*) FROM users WHERE name = 'xka' OR name = 'xka2'; (count)db.Model(&User{}).Where("name = ?", "xka").Count(&count)SELECT count(*) FROM users WHERE name = 'xka'; (count)db.Table("deleted_users").Count(&count)SELECT count(*) FROM deleted_users;db.Table("deleted_users").Select("count(distinct(name))").Count(&count)SELECT count( distinct(name) ) FROM deleted_users; (count)
注意 :Count
必须是链式查询的最后一个操作 ,因为它会覆盖前面的 SELECT
,但如果里面使用了 count
时不会覆盖
更新操作
官方中文文档:
更新 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.https://gorm.io/zh_CN/docs/update.html
保存所有字段
Save
会保存所有的字段,即使字段是零值
//从数据库中查询出需要更改的数据
db.First(&user)
//给user修改值
user.Name = "jinzhu 2"
user.Age = 100
//将修改值保存到数据库中
db.Save(&user)
// UPDATE users SET name='jinzhu 2', age=100, birthday='2016-01-01', updated_at = '2013-11-17 21:34:10' WHERE id=111;
更新单个列
当使用 Update
更新单列时,需要有一些条件,否则将会引起错误 ErrMissingWhereClause
,阻止全局更新。当使用 Model
方法,并且值中有主键值时,主键将会被用于构建条件。
阻止全局更新 :如果在没有任何条件的情况下执行批量更新,默认情况下,GORM 不会执行该操作,并返回 ErrMissingWhereClause
错误。对此,你必须加一些条件,或者使用原生 SQL,或者启用 AllowGlobalUpdate
模式
// 条件更新
db.Model(&User{}).Where("active = ?", true).Update("name", "hello")
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE active=true;// User 的 ID 是 `111`
db.Model(&user).Update("name", "hello")
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;// 根据条件和 model 的值进行更新
db.Model(&user).Where("active = ?", true).Update("name", "hello")
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true;
更新多列
Updates
方法支持 struct
和 map[string]interface{}
参数。当使用 struct
更新时,默认情况下,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, "active": false})
// UPDATE users SET name='hello', age=18, active=false, updated_at='2013-11-17 21:34:10' WHERE id=111;
更新选定字段
更新时选定、忽略某些字段,您可以使用 Select
、Omit
// Select with Map
// User's ID is `111`:
db.Model(&user).Select("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "active": false})
// UPDATE users SET name='hello' WHERE id=111;db.Model(&user).Omit("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "active": false})
// UPDATE users SET age=18, active=false, updated_at='2013-11-17 21:34:10' WHERE id=111;// Select with Struct (select zero value fields)
db.Model(&user).Select("Name", "Age").Updates(User{Name: "new_name", Age: 0})
// UPDATE users SET name='new_name', age=0 WHERE id=111;// Select all fields (select all fields include zero value fields)
db.Model(&user).Select("*").Updates(User{Name: "jinzhu", Role: "admin", Age: 0})// Select all fields but omit Role (select all fields include zero value fields)
db.Model(&user).Select("*").Omit("Role").Updates(User{Name: "jinzhu", Role: "admin", Age: 0})
更新 Hook
Hook :对象生命周期,Hook 是在创建、查询、更新、删除等操作之前、之后调用的函数。如果您已经为模型定义了指定的方法,它会在创建、更新、查询、删除时自动被调用。如果任何回调返回错误,GORM 将停止后续的操作并回滚事务。(事务)
func (u *User) BeforeUpdate(tx *gorm.DB) (err error) {if u.readonly() {err = errors.New("read only user")}return
}// 在同一个事务中更新数据
func (u *User) AfterUpdate(tx *gorm.DB) (err error) {if u.Confirmed {tx.Model(&Address{}).Where("user_id = ?", u.ID).Update("verfied", true)}return
}
无Hooks更新
上面的更新操作会自动运行 model 的 BeforeUpdate
, AfterUpdate
方法,更新 UpdatedAt
时间戳, 在更新时保存其 Associations
, 如果你不想调用这些方法,你可用 UpdateColumn,
UpdateColumns
// 更新单个属性,类似于 `Update`
db.Model(&user).UpdateColumn("name", "hello")UPDATE users SET name='hello' WHERE id = 111;// 更新多个属性,类似于 `Updates`
db.Model(&user).UpdateColumns(User{Name: "hello", Age: 18})UPDATE users SET name='hello', age=18 WHERE id = 111;
批量更新
如果您尚未通过 Model
指定记录的主键,则 GORM 会执行批量更新。
// 根据 struct 更新
db.Model(User{}).Where("role = ?", "admin").Updates(User{Name: "hello", Age: 18})
// UPDATE users SET name='hello', age=18 WHERE role = 'admin';// 根据 map 更新
db.Table("users").Where("id IN ?", []int{10, 11}).Updates(map[string]interface{}{"name": "hello", "age": 18})
// UPDATE users SET name='hello', age=18 WHERE id IN (10, 11);
使用 struct 更新时,只会更新非零值字段,若想更新所有字段,请使用map[string]interface{}。
db.Table("users").Where("id IN (?)", []int{10, 11}).Updates(map[string]interface{}{"name": "hello", "age": 18})UPDATE users SET name='hello', age=18 WHERE id IN (10, 11);// 使用 struct 更新时,只会更新非零值字段,若想更新所有字段,请使用map[string]interface{}
db.Model(User{}).Updates(User{Name: "hello", Age: 18})UPDATE users SET name='hello', age=18;// 使用 `RowsAffected` 获取更新记录总数
db.Model(User{}).Updates(User{Name: "hello", Age: 18}).RowsAffected
删除操作
官方中文文档:
删除 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.https://gorm.io/zh_CN/docs/delete.html
基本删除
注意:删除记录时,请确保主键字段有值,GORM 会通过主键去删除记录,如果主键为空,GORM 会删除该 model 的所有记录。
此处的email已经提前有了id值。
// 删除现有记录
db.Delete(&email)DELETE from emails where id=10;// 为删除 SQL 添加额外的 SQL 操作
db.Set("gorm:delete_option", "OPTION (OPTIMIZE FOR UNKNOWN)").Delete(&email)DELETE from emails where id=10 OPTION (OPTIMIZE FOR UNKNOWN);
根据主键删除
db.Delete(&User{}, 10)
// DELETE FROM users WHERE id = 10;db.Delete(&User{}, "10")
// DELETE FROM users WHERE id = 10;db.Delete(&users, []int{1,2,3})
// DELETE FROM users WHERE id IN (1,2,3);
Delete Hook
对于删除操作,GORM 支持 BeforeDelete
、AfterDelete
Hook,在删除记录时会调用这些方法 。
// 在同一个事务中更新数据
func (u *User) AfterDelete(tx *gorm.DB) (err error) {if u.Confirmed {tx.Model(&Address{}).Where("user_id = ?", u.ID).Update("invalid", false)}return
}
批量删除
如果指定的值不包括主属性,那么 GORM 会执行批量删除,它将删除所有匹配的记录。
db.Where("email LIKE ?", "%jinzhu%").Delete(&Email{})
// DELETE from emails where email LIKE "%jinzhu%";db.Delete(&Email{}, "email LIKE ?", "%jinzhu%")
// DELETE from emails where email LIKE "%jinzhu%";
阻止全局删除
如果没有任何条件的情况下执行批量删除,GORM 不会执行该操作,返回ErrMissingWhereClaus
错误。对此,你必须加一些条件,或者使用原生 SQL,或者启用 AllowGlobalUpdate
模式。
db.Delete(&User{}).Error // gorm.ErrMissingWhereClausedb.Where("1 = 1").Delete(&User{})
// DELETE FROM `users` WHERE 1=1db.Exec("DELETE FROM users")
// DELETE FROM usersdb.Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&User{})
// DELETE FROM users
软删除
如果您的模型包含了一个 gorm.deletedat
字段(gorm.Model
已经包含了该字段),它将自动获得软删除的能力!拥有软删除能力的模型调用 Delete
时,记录不会从数据库被真正删除。但 GORM会将 DeletedAt
置为当前时间, 并且你不能再通过普通的查询方法找到该记录。
// 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;
如果不想引入 gorm.Model
,可以这样启用软删除特性:
type User struct {ID intDeleted gorm.DeletedAtName string
}
查找被软删除的记录
可使用 Unscoped
找到被软删除的记录 。
db.Unscoped().Where("age = 20").Find(&users)
// SELECT * FROM users WHERE age = 20;
以上就是本次所有关于GORM的增删查改的学习,谢谢观看!如有什么错误请各位大神在评论区指出。
Golang学习笔记之GORM基础使用(二)相关推荐
- Golang学习笔记之GORM基础使用(一)
本文章主要学习了GORM的基础知识,数据库的连接以及数据库表的建立的多种方法.本文为学习笔记,通过GORM官方中文文档和李文周的博客学习整理而成. gorm是一个使用Go语言编写的ORM框架.它文档齐 ...
- golang学习笔记(7)-gorm实现修改功能
gorm实现修改功能 目录 gorm实现修改功能 准备工作 保存所有字段 更新单个列 更新多列 更新选定字段 批量更新 根据子查询进行更新 使用 SQL 表达式更新 准备工作 建立数据库连接 impo ...
- UE5学习笔记01(基础操作二)
1.Outliner被翻译成"大纲". 2.当按住Shift键移动一个物体时,摄像机会追随被移动的物体,形成一种第三人称视角的感觉. 3.在Outliner中选择一个或者多个物体之 ...
- golang学习笔记(基础篇)
LCY~~Golang学习笔记 一.Go语言开发环境 ##安装Go开发包以及VsCode Go开发包与vscode配置安装教程网址:https://www.liwenzhou.com/posts/Go ...
- 前端学习笔记之CSS3基础语法与盒模型(二)
前端学习笔记之 CSS3基础语法与盒模型 CSS3简介 CSS(cascading style sheet,层叠式样式表)是用来给HTML标签添加样式的语言 CSS3是CSS的最新版本,增加了大量的样 ...
- 118云原生编程语言Golang学习笔记
Golang学习笔记 文章目录 1.Go简介 1.1 简介 1.2 设计初衷 1.3 Golang vs Java 1.4 应用领域 1.5 用go语言的公司 2.Go下载和安装 2.1 开发工具 2 ...
- 吴恩达《机器学习》学习笔记七——逻辑回归(二分类)代码
吴恩达<机器学习>学习笔记七--逻辑回归(二分类)代码 一.无正则项的逻辑回归 1.问题描述 2.导入模块 3.准备数据 4.假设函数 5.代价函数 6.梯度下降 7.拟合参数 8.用训练 ...
- 学习笔记之数据可视化(二)—— 页面布局(下)
续上一章 2.7 地图区域(.map) 2.7.1 实现步骤: 2.8 用户统计模块 2.8.1 布局: 2.8.2 柱状图 2.9 订单模块 2.9.1 订单区域布局 2.9.2 订单区域(orde ...
- 学习笔记之数据可视化(二)——页面布局(上)
~续上一章 2. 项目页面布局 2.1 基础布局 2.1.1 PC端屏幕宽度适配设置 2.1.2 主体容器viewport背景图片 2.1.3 HTML结构 2.1.4 css样式代码 2.2 边框图 ...
最新文章
- c#_Func和Action委托简介
- 第一周冲刺_周三总结
- python怎么读取pdf为文本_python怎么读取pdf文本内容
- 51nod 2020 排序相减(暴力解法)
- window.onload 函数不执行处理
- 推荐系统-Task03离线物料系统的构建
- Python+Selenium+Edge浏览器安装与简单运行(1/2)
- 智能制造与数字化工厂
- Java并发编程之安全发布对象的四种方法
- 【计算机网络自顶向下方法】Web页面请求的历程
- 网络攻防技术——shellcode编写
- 微信小程序 人脸识别功能 代码 wx.faceDetect
- java bsh介绍_BeanShell简介
- 秒杀系统企业级实战应用之真实工业界案例视频
- 苹果电脑python编译器_Mac版-python环境配置(二):编译器pycharm下载安装
- python创建空字典什么意思_Python3基础 dict 创建字典 空字典
- 制定科学学习计划的重要性
- B站股权曝光:陈睿持股12.9%阿里持股7.9% 寻求双重主要上市
- uTorrent设置,防止出现磁盘负荷100%
- 80后,我们难忘的电视剧