06-更新数据
目录
1. save (更新/创建)
主键
如果查到,更新数据
主键如果未查到,插入一条数据
liuBei := xiShu {
ID: 9,
Name: "GuanYu",
Age: 30,
}
db.Save(&liuBei)
- 示例
package main
import (
"database/sql"
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"time"
)
type User struct {
ID int64
Age int64
Name string
Email string
Company string
}
func main() {
db,sqlDB,_ := connect()
defer sqlDB.Close()
user := User{
ID: 2,
Name: "GuanDi",
}
db.Save(&user)
fmt.Println(user)
}
func connect() (db *gorm.DB,sqlDB *sql.DB,err error) {
dsn := "root:40010355@tcp(127.0.0.1:3306)/crow?charset=utf8&parseTime=True&loc=Local"
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
sqlDB,_ = db.DB()
if err != nil {
fmt.Printf(err.Error())
defer sqlDB.Close()
}else {
fmt.Printf("OK\n")
sqlDB.SetMaxIdleConns(10)
sqlDB.SetMaxOpenConns(100)
sqlDB.SetConnMaxLifetime(time.Hour)
}
return
}
2. Update(单列修改)
目前表:
mysql> select * from xi_shu;
+----+------------+------+
| id | name | age |
+----+------------+------+
| 1 | LiuBei | 28 |
| 2 | GuanYu | 22 |
| 3 | ZhangFei | 20 |
+----+------------+------+
3 rows in set (0.01 sec)
2.1 根据主键修改单列
2.1.1 使用
- 样例
db.Model(&User{ID:2}).Update("name", "WuSheng")
- 说明
前边model中指明的条件,只有主键才能用来查询
如果要查其他键可以用Where来查询
2.1.2 示例
- 代码
结构体中我们设置了三个成员,后边演示中可以看到,只有主键的 ID=2可以用来定位
func main() {
db,sqlDB,_ := connect()
defer sqlDB.Close()
user := User {
ID: 2,
Name: "GuanYu",
Age: 30,
}
//var users []xiShu
db.Model(&user).Update("name", "WuSheng")
fmt.Println(user)
}
- 输出
OK
&{2 WuSheng 30}
可见,不管是否查到,是否更新,用来查询的结构体数据是不会发生变化的。
- 数据库的表
mysql> select * from xi_shu where id = 2;
+----+---------+------+
| id | name | age |
+----+---------+------+
| 2 | WuSheng | 22 |
+----+---------+------+
1 row in set (0.00 sec)
可见,表的数据中,仅按着Update()修改了name列的值
而不会因为根据查询条件的机构体改变。
2.2 单列修改(不论是否主键)
db.Model(&xiShu{}).Where("name = ?","GuanYu").Update("name", "WuSheng")
说明:
Model
指定表
Where
查找要修改行,
Update
指定要修改列和内容(语法上仅能指定一列)
3. Updates(多列修改)
3.1 基本使用
- 使用Map
db.Model(&User{}).Where("name = ?","GuanYu").Updates(map[string]interface{}{"name": "WuSheng", "age": 99})
- 使用 struct
db.Model(&xiShu{}).Where("name = ?","GuanYu").Updates(&xiShu{Name: "WuSheng",Age: 99})
3.2 Select(限制修改字段范围)
说明:Select限制哪些字段允许修改,Update中指定列不在此范围的不可更改。
db.Model(&User{ID:2}).Select("name").Updates(map[string]interface{}{"name": "WuSheng", "age": 99})
3.2 Omit(排除修改字段范围)
说明:Select限制哪些字段
不
允许修改,Update中指定列在此范围的不可更改。
db.Model(&xiShu{ID:2}).Omit("name").Updates(map[string]interface{}{"name": "WuSheng", "age": 99})
4. 钩子
4.1 创建钩子
-
说明
关于更新,允许 AfterSave、AfterUpdate两种,更新时会调用。 -
示例
如果权限是admin,则返回错误。
func (u *User) BeforeUpdate(tx *gorm.DB) (err error) {
if u.Role == "admin" {
return errors.New("admin user not allowed to update")
}
return
}
4.2 不使用钩子
如果不想使用钩子可用UpdateColumn或UpdateColumns。
- UpdateColumn
说明:单列不使用钩子
db.Model(&xiShu{ID:2}).UpdateColumn("name", "WuSheng")
- UpdateColumns
说明:多列不使用钩子
db.Model(&user).UpdateColumns(User{Name: "WuSheng", Age: 99})
5. RowsAffected(修改影响行数)
func main() {
db,sqlDB,_ := connect()
defer sqlDB.Close()
result := db.Table("users").Where("id IN (?)", []int{1,2,3}).Update("Age",11).RowsAffected
fmt.Println(result)
}
输出
OK
3
1、2、3 三行被修改,输出为3。
6. Expr(带有表达式的sql更新)
- 示例
将id=2 的用户 年龄X2+100
func main() {
db,sqlDB,_ := connect()
defer sqlDB.Close()
user := User{
ID: 2,
}
db.Model(&user).Update("age", gorm.Expr("age * ? + ?", 2, 100))
fmt.Println(user)
}
表结果
mysql> select * from xi_shu where id = 2;
+----+---------+------+
| id | name | age |
+----+---------+------+
| 2 | WuSheng | 144 |
+----+---------+------+
1 row in set (0.00 sec)
如上,关羽的年龄从22修改为144