1. save (更新/創(chuàng)建)
主鍵如果查到言沐,更新數(shù)據(jù)
主鍵如果未查到,插入一條數(shù)據(jù)
liuBei := xiShu {
ID: 9,
Name: "GuanYu",
Age: 30,
}
db.Save(&liuBei)
- 示例
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type xiShu struct {
ID int64
Name string
Age int64
}
func(xiShu) TableName() string {
return "xi_shu"
}
func main() {
db,_ := connect()
defer db.Close()
//db.CreateTable(&xiShu{})
liuBei := xiShu {
ID: 9,
Name: "LiuBei",
Age: 30,
}
db.Save(&liuBei)
}
func connect() (db *gorm.DB,err error) {
db, err = gorm.Open("mysql", "root:40010355@tcp(127.0.0.1:3306)/crow?charset=utf8&parseTime=True&loc=Local")
if err != nil {
fmt.Printf(err.Error())
defer db.Close()
}else {
fmt.Printf("OK\n")
db.DB().SetMaxIdleConns(10)
db.DB().SetMaxOpenConns(100)
}
return
}
2. Update(單列修改)
目前表:
mysql> select * from xi_shu;
+----+------------+------+
| id | name | age |
+----+------------+------+
| 1 | LiuBei | 28 |
| 2 | GuanYu | 22 |
| 3 | ZhangFei | 20 |
| 4 | ZhaoYun | 18 |
| 5 | ZhuGeLiang | 20 |
| 6 | MaChao | 20 |
| 7 | PangTong | 25 |
| 8 | HuangZhong | 35 |
+----+------------+------+
9 rows in set (0.01 sec)
2.1 根據(jù)主鍵修改單列
db.Model(&xiShu{ID: 2}).Update("name", "WuSheng")
- 示例
結(jié)構(gòu)體中我們設(shè)置了三個成員酣栈,后邊演示中可以看到险胰,只有主鍵的 ID=2生效
func main() {
db,_ := connect()
defer db.Close()
user := xiShu {
ID: 2,
Name: "GuanYu",
Age: 30,
}
//var users []xiShu
result := db.Model(&user).Update("name", "WuSheng")
fmt.Println(result.Value)
}
說明:
我想說的是,如果結(jié)構(gòu)體定義了很多成員矿筝,只有第一個會生效
Name和Age 的值對定位沒有影響起便。
因此,Age:30 依然會查到第二行窖维,然后修改該行榆综。
- 輸出
OK
&{2 WuSheng 30}
可見,result的值是 結(jié)構(gòu)體 user 的值基礎(chǔ)上铸史,做了Update() 的修改
- 數(shù)據(jù)庫的表
mysql> select * from xi_shu where id = 2;
+----+---------+------+
| id | name | age |
+----+---------+------+
| 2 | WuSheng | 22 |
+----+---------+------+
1 row in set (0.00 sec)
可見鼻疮,表的數(shù)據(jù)中,僅按著Update()修改了name列的值
而age列沒因為結(jié)構(gòu)體user的Age值而改變琳轿,和輸出中result的值不同判沟。
2.2 全部行修改
按上邊的結(jié)果,我們可以推測崭篡,要修改所有行的name值可以:
func main() {
db,_ := connect()
defer db.Close()
result := db.Model(&xiShu{}).Update("name", "WuSheng")
fmt.Println(result.Value)
}
2.3 使用組合條件更新單個屬性
db.Model(&xiShu{}).Where("name = ?","GuanYu").Update("name", "WuSheng")
2.4 使用 map 更新多個屬性
db.Model(&xiShu{}).Where("name = ?","GuanYu").Updates(map[string]interface{}{"name": "WuSheng", "age": 99})
2.5 使用 struct 更新多個屬性
db.Model(&xiShu{}).Where("name = ?","GuanYu").Updates(&xiShu{Name: "WuSheng",Age: 99})
3. Updates
3.1 限制修改字段范圍
func main() {
db,_ := connect()
defer db.Close()
db.Model(&xiShu{ID:2}).Select("name").Updates(map[string]interface{}{"name": "WuSheng", "age": 99})
}
表修改結(jié)果:
mysql> select * from xi_shu;
+----+------------+------+
| id | name | age |
+----+------------+------+
| 1 | LiuBei | 28 |
| 2 | WuSheng | 22 |
| 3 | ZhangFei | 20 |
| 4 | ZhaoYun | 18 |
| 5 | ZhuGeLiang | 20 |
| 6 | MaChao | 20 |
+----+------------+------+
6 rows in set (0.00 sec)
說明:Update()指定了name和age兩個字段挪哄,但是Select限制了修改范圍是name字段,因此age不會改變琉闪。
3.2 限制不修改字段
db.Model(&xiShu{ID:2}).Omit("name").Updates(map[string]interface{}{"name": "WuSheng", "age": 99})
表修改結(jié)果
mysql> select * from xi_shu;
+----+------------+------+
| id | name | age |
+----+------------+------+
| 1 | LiuBei | 28 |
| 2 | GuanYu | 99 |
| 3 | ZhangFei | 20 |
| 4 | ZhaoYun | 18 |
| 5 | ZhuGeLiang | 20 |
| 6 | MaChao | 20 |
+----+------------+------+
6 rows in set (0.00 sec)
說明:Update()指定了name和age兩個字段迹炼,但是Omit限制了修改范圍是不能是name字段,因此age不會改變塘偎。
4. 不使用鉤子
4.1 UpdateColumn/UpdateColumns
上文 2.
疗涉,3.
中如果有鉤子方法,則會使用鉤子吟秩,如果不想使用鉤子可用UpdateColumn或UpdateColumns咱扣。
- UpdateColumn
db.Model(&xiShu{ID:2}).UpdateColumn("name", "WuSheng")
- UpdateColumns
db.Model(&user).UpdateColumns(User{Name: "WuSheng", Age: 99})
- 完整示例
如果使用
Update
修改,則會調(diào)用BeforeUpdate
涵防,則 name結(jié)果會被修改為BeforeUpdate
的參數(shù)HaHa
但使用了UpdateColumn
則會執(zhí)行UpdateColumn
中制定的參數(shù)闹伪,修改name
為WuSheng
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type xiShu struct {
ID int64
Name string
Age int64
}
func(xiShu) TableName() string {
return "xi_shu"
}
//鉤子
func (LiuBei *xiShu) BeforeUpdate(scope *gorm.Scope) error {
scope.SetColumn("Name", "HaHa")
return nil
}
func main() {
db,_ := connect()
defer db.Close()
//不使用鉤子
result := db.Model(&xiShu{ID:2}).UpdateColumn("name", "WuSheng")
fmt.Println(result.Value)
}
func connect() (db *gorm.DB,err error) {
db, err = gorm.Open("mysql", "root:40010355@tcp(127.0.0.1:3306)/crow?charset=utf8&parseTime=True&loc=Local")
if err != nil {
fmt.Printf(err.Error())
defer db.Close()
}else {
fmt.Printf("OK\n")
db.DB().SetMaxIdleConns(10)
db.DB().SetMaxOpenConns(100)
}
return
}
4.2 批量修改不使用鉤子
db.Table("users").Where("id IN (?)", []int{10, 11}).Update(age: 20)
- 示例(單行修改使用鉤子)
表原來的數(shù)據(jù)
mysql> select * from xi_shu;
+----+------------+------+
| id | name | age |
+----+------------+------+
| 1 | LiuBei | 28 |
| 2 | WuSheng | 10 |
| 3 | ZhangFei | 20 |
| 4 | ZhaoYun | 18 |
| 5 | ZhuGeLiang | 20 |
| 6 | MaChao | 20 |
+----+------------+------+
6 rows in set (0.00 sec)
代碼
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type xiShu struct {
ID int64
Name string
Age int64
}
func(xiShu) TableName() string {
return "xi_shu"
}
func (LiuBei *xiShu) BeforeUpdate(scope *gorm.Scope) error {
scope.SetColumn("Age", 10)
return nil
}
func main() {
db,_ := connect()
defer db.Close()
result := db.Model(&xiShu{ID: 2}).Update("Age",9)
fmt.Println(result.Value)
}
func connect() (db *gorm.DB,err error) {
db, err = gorm.Open("mysql", "root:40010355@tcp(127.0.0.1:3306)/crow?charset=utf8&parseTime=True&loc=Local")
if err != nil {
fmt.Printf(err.Error())
defer db.Close()
}else {
fmt.Printf("OK\n")
db.DB().SetMaxIdleConns(10)
db.DB().SetMaxOpenConns(100)
}
return
}
表修改結(jié)果
mysql> select * from xi_shu;
+----+------------+------+
| id | name | age |
+----+------------+------+
| 1 | LiuBei | 28 |
| 2 | WuSheng | 10 |
| 3 | ZhangFei | 20 |
| 4 | ZhaoYun | 18 |
| 5 | ZhuGeLiang | 20 |
| 6 | MaChao | 20 |
+----+------------+------+
6 rows in set (0.00 sec)
BeforeUpdate參數(shù)年齡10,而Update參數(shù)年齡 9
結(jié)果可見壮池,單行修改使用了BeforeUpdate參數(shù)10
- 示例(多行修改不使用鉤子)
上例中main函數(shù)修改如下
func main() {
db,_ := connect()
defer db.Close()
result := db.Table("xi_shu").Where("id IN (?)", []int{1,2,3}).Update("Age",9)
fmt.Println(result.Value)
}
表修改結(jié)果
mysql> mysql> select * from xi_shu;
+----+------------+------+
| id | name | age |
+----+------------+------+
| 1 | LiuBei | 9 |
| 2 | WuSheng | 9 |
| 3 | ZhangFei | 9 |
| 4 | ZhaoYun | 18 |
| 5 | ZhuGeLiang | 20 |
| 6 | MaChao | 20 |
+----+------------+------+
6 rows in set (0.00 sec)
如上可見偏瓤,1、2椰憋、3行都修改為9厅克,使用了Update參數(shù),而不是BeforeUpdate的參數(shù)橙依。
注意:即使where中id=1,也是多行修改证舟,只不過是查到了一行而以硕旗,因此鉤子不生效。
5. RowsAffected(修改影響行數(shù))
func main() {
db,_ := connect()
defer db.Close()
result := db.Table("xi_shu").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,_ := connect()
defer db.Close()
result := db.Model(&xiShu{ID: 2}).Update("age", gorm.Expr("age * ? + ?", 2, 100))
fmt.Println(result.Value)
}
表結(jié)果
mysql> select * from xi_shu where id = 2;
+----+---------+------+
| id | name | age |
+----+---------+------+
| 2 | WuSheng | 144 |
+----+---------+------+
1 row in set (0.00 sec)
如上墙基,關(guān)羽的年齡從22修改為144