GORM的增删改查

一下列出了部分内容,详情可以查看官方文档,官方文档路径:

https://gorm.io/zh_CN/docs/

https://www.kancloud.cn/sliver_horn/gorm/1861152

package main

import (
    "fmt"
    "strconv"
    "time"

    _ "github.com/go-sql-driver/mysql"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

// 定义一个雇员
type Emp struct {
    Id         int
    Name       string
    Age        int
    Gender     []uint8    // 对应数据库中的bit
    Birthday   *time.Time // 对应数据库中的date
    Salary     float32
    Department string
}

// 定义一个学生
type Stu struct {
    gorm.Model // 定义模型,将ID,created_at,updated_at,deleted_at添加进结构体
    Name       string
    Age        int
}

// type Model struct {
//     ID        uint `gorm:"primarykey"`
//     CreatedAt time.Time
//     UpdatedAt time.Time
//     DeletedAt DeletedAt `gorm:"index"`
// }

// 实例化结构体的时候,time.Time输入字符串报错,所以这里定义了一个将字符串转换成时间的函数
func s2t(s string) time.Time {
    t, _ := time.Parse("2006-01-02", s)
    return t
}

func main() {
    dsn := "root:123456@(127.0.0.1:3306)/golang?charset=utf8mb4&parseTime=true"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        fmt.Printf("connect DB failed, err:%v\n", err)
        return
    }
    db.Table("stus").AutoMigrate(&Stu{}) // 新建一张名为stus的表
    stu1 := make([]Stu, 0)               // 定义一个切片
    for i := 0; i < 100; i++ {           // 创建100条数据
        stu1 = append(stu1, Stu{Name: "stu" + fmt.Sprint(i), Age: 20 + i})
    }
    db.Create(&stu1) // 将数据写入数据库

    // 查询
    // 单个查询
    var stu2 Stu
    var stu2s []Stu
    ret := db.Debug().First(&stu2) // 查询第一条记录,将他赋值给stu2,加上Debug可以看到查询语句
    fmt.Println(stu2)
    db.Take(&stu2) // 查询随机一条记录,将他赋值给stu2
    fmt.Println(stu2)
    db.Debug().Last(&stu2) // 查询最后一条记录,将他赋值给stu2
    fmt.Println(stu2)
    fmt.Println(ret.RowsAffected) // 返回查询到的数量
    fmt.Println(ret.Error)        // 返回错误
    // where查询
    db.Where("name = ?", "stu20").First(&stu2) // 查询名称为stu20的第一条记录
    fmt.Println(stu2)
    db.Where("name LIKE ?", "%2%").Find(&stu2s) // 查询name包含2的
    db.Where(&Stu{Name: "stu72"}).First(&stu2)  // 查询的时候会带上结构体里面的id,需要注意,在查询的时候需要保证stu2里面的id为空,不然会带上
    fmt.Println(stu2)
    db.Where(map[string]interface{}{"name": "stu72", "age": 92}).First(&stu2)
    fmt.Println(stu2)

    // 更新
    db.Where("name = ?", "stu20").First(&stu2)                                                             // 需要先拿到一个值
    db.Model(&stu2).Update("name", "lisi")                                                                 // 这个时候会用上一句查询的结果的id去更新
    db.Model(&stu2).Where("name = ?", "stu10").Update("name", "hello")                                     // 将名字为stu10的条目名字改为hello
    db.Model(&stu2).Where("name=?", "hello").Updates(map[string]interface{}{"name": "zhangan", "age": 22}) // 通过map更新多个字段
    db.Model(&stu2).Where("name=?", "zhangan").Updates(Stu{Name: "王五", Age: 23})                           // 通过结构体更新多个字段,注意结构体不能更新value为空的字段

    // 删除
    // 如果您的模型包含了一个 gorm.deletedat 字段(gorm.Model 已经包含了该字段),它将自动获得软删除的能力!
    // 删除条目不会真正删除数据库内容,只会更新删除时间,实际上执行的是update操作
    db.Debug().Where("name LIKE ?", "%i%").Delete(&Stu{}) // 删除包含i的条目
    // UPDATE `stus` SET `deleted_at`='2021-09-21 16:05:40.76' WHERE name LIKE '%i%' AND `stus`.`deleted_at` IS NULL
    // +----+-------------------------+-------------------------+-------------------------+------+------+
    // | id | created_at              | updated_at              | deleted_at              | name | age  |
    // +----+-------------------------+-------------------------+-------------------------+------+------+
    // | 21 | 2021-09-21 06:16:19.780 | 2021-09-21 07:33:43.694 | 2021-09-21 07:57:56.930 | lisi |   40 |
    // +----+-------------------------+-------------------------+-------------------------+------+------+
    db.Debug().Delete(&Stu{}, 20) // 删除id=20的条目
    // UPDATE `stus` SET `deleted_at`='2021-09-21 16:04:45.035' WHERE `stus`.`id` = 20 AND `stus`.`deleted_at` IS NULL
    db.Debug().Where("name = ?", "zhangan").Delete(&Stu{}) // 删除name=zhangan的条目
    // UPDATE `stus` SET `deleted_at`='2021-09-21 16:04:45.056' WHERE name = 'zhangan' AND `stus`.`deleted_at` IS NULL
    db.Delete(&Stu{})                                       // 该条目将会报错,禁止全部删除
    db.Unscoped().Where("name = ?", "stu90").Delete(&Stu{}) // 该语句将会永久删除条目
    db.Where("name=?", "lisi").Find(&stu2)                  // 由于lisi被软删除了,所以这个时候这个语句查询不到
    fmt.Println(stu2)                                       // 将显示结构体的0值
    db.Unscoped().Where("name=?", "lisi").Find(&stu2)       // 该语句将会拿到数据库中的值
    fmt.Println(stu2)

}

 

posted on 2021-09-21 16:20  torotoise512  阅读(266)  评论(0编辑  收藏  举报