美文网首页
gorm-更新

gorm-更新

作者: 玄德公笔记 | 来源:发表于2022-02-10 15:58 被阅读0次

    1. save (更新/创建)

    主键如果查到,更新数据
    主键如果未查到,插入一条数据

        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 根据主键修改单列

    db.Model(&xiShu{ID: 2}).Update("name", "WuSheng")
    
    • 示例

    结构体中我们设置了三个成员,后边演示中可以看到,只有主键的 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)
    }
    

    说明:
    我想说的是,如果结构体定义了很多成员,只有第一个会生效
    Name和Age 的值对定位没有影响。
    因此,Age:30 依然会查到第二行,然后修改该行。

    • 输出
    OK
    &{2 WuSheng 30}
    

    可见,result的值是 结构体 user 的值基础上,做了Update() 的修改

    • 数据库的表
    mysql> select * from xi_shu where id = 2;
    +----+---------+------+
    | id | name    | age  |
    +----+---------+------+
    |  2 | WuSheng |   22 |
    +----+---------+------+
    1 row in set (0.00 sec)
    

    可见,表的数据中,仅按着Update()修改了name列的值
    而age列没因为结构体user的Age值而改变,和输出中result的值不同。

    2.2 全部行修改

    按上边的结果,我们可以推测,要修改所有行的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})
    }
    

    表修改结果:

    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})
    

    表修改结果

    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修改,则会调用BeforeUpdate,则 name结果会被修改为BeforeUpdate的参数 HaHa
    但使用了UpdateColumn则会执行UpdateColumn中制定的参数,修改nameWuSheng

    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)
    
    • 示例(单行修改使用钩子)
      表原来的数据
    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
    }
    

    表修改结果

    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参数年龄10,而Update参数年龄 9
    结果可见,单行修改使用了BeforeUpdate参数10

    • 示例(多行修改不使用钩子)
      上例中main函数修改如下
    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)
    }
    

    表修改结果

    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参数,而不是BeforeUpdate的参数。
    注意:即使where中id=1,也是多行修改,只不过是查到了一行而以,因此钩子不生效。

    5. RowsAffected(修改影响行数)

    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)
    }
    

    表结果

    mysql> select * from xi_shu where id = 2;
    +----+---------+------+
    | id | name    | age  |
    +----+---------+------+
    |  2 | WuSheng |  144 |
    +----+---------+------+
    1 row in set (0.00 sec)
    

    如上,关羽的年龄从22修改为144

    相关文章

      网友评论

          本文标题:gorm-更新

          本文链接:https://www.haomeiwen.com/subject/cdtgkrtx.html