目录
Gorm官方文档GORM 指南 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.
Gorm定义model与连接数据库
gorm定义Model是通过结构体的方式,gorm使用名为ID的字段作为主键,使用结构体的蛇形复数作为表名(在没有定义表名的情况下),字段名的蛇形作为列名(在没有主动定义列名的情况下)
使用CreatedAt,UpdatedAt字段作为创建,更新时间。
// gorm.Model 的定义
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
为model定义表名
type Product struct {
Code string // 设置默认值
Price uint // 设置默认值
}
func (p Product) TableName() string {
return "product"
}
连接数据库
dsn := "root:123456@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(
mysql.Open(dsn),
&gorm.Config{})
if err != nil {
panic("failed to connect database")
}
创建数据
func AddProduct(db *gorm.DB) {
// 单条创建
p := Product{Code: "D41", Price: 100}
// Create需要传指针
res := db.Create(&p)
fmt.Println(res.Error)
fmt.Println(p.Code)
// 多条创建
p1 := []*Product{{Code: "D43", Price: 100}, {Code: "D40", Price: 100}, {Code: "D39", Price: 100}}
// Create的接收类型为interface{},空接口,然后传入之后,再switch进行变量类型的区分
res = db.Create(p1)
fmt.Println(res.Error)
for _, p := range p1 {
fmt.Println(p.Code)
}
// 不处理冲突,创建一条数据
p = Product{Code: "D42", Price: 100}
db.Clauses(clause.OnConflict{DoNothing: true}).Create(&p)
}
查询数据
// SelectProduct 查询数据
func SelectProduct(db *gorm.DB) {
// 声明一条记录(结构体)
// 获取第一条记录(主键升序)。查询不到数据则返回 ErrRecordNotFound
p := &Product{}
res := db.First(p) // SELECT * FROM Product ORDER BY id LIMIT 1
fmt.Println(res.Error)
fmt.Println(*p)
// 查询多条数据
// 声明结构体数组
ps := make([]*Product, 0)
// Find中要传一个结构体指针切片的指针
result := db.Where("Code IN ?", []string{"D42", "D41"}).Find(&ps)
fmt.Println(result.Error)
for _, re := range ps {
fmt.Println(*re)
}
// 模糊查询
res = db.Where("Code LIKE %4%").Find(&ps)
fmt.Println(res.Error)
for _, re := range ps {
fmt.Println(*re)
}
// 用map查询
res = db.Where(map[string]interface{}{"Code": "D42"}).Find(&ps)
fmt.Println(res.Error)
for _, re := range ps {
fmt.Println(*re)
}
}
更新数据
db.Model()中传结构体的指针,其实就相当于选择这个表查询,&结构体名{}
func Update(db *gorm.DB) {
res := db.Model(&User{}).Where("age>?", 19).Update("name", "hello")
fmt.Println(res.Error)
res = db.Model(&User{}).Where("name = ?", "hello").Update("Age", "21")
fmt.Println(res.Error)
user := User{}
db.Model(&user).Where("Name = ?", "hello").Updates(User{"abc", "18"})
// map更新选定字段,更新name字段
db.Model(&User{}).Where("name = ?", "hi").Select("name", "age").Updates(map[string]interface{}{"name": "hi", "age": "180"})
// SQL 表达式更新
db.Model(&User{}).Where("name = ?", "B").Update("age", gorm.Expr("age * ? + ?", 2, 100))
}
删除数据-----物理删除
删除数据-----软删除
如果您的模型包含了一个 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 int
Deleted gorm.DeletedAt
Name string
}
查找被软删除的记录
您可以使用 Unscoped
找到被软删除的记录
db.Unscoped().Where("age = 20").Find(&users)
// SELECT * FROM users WHERE age = 20;
永久删除
您也可以使用 Unscoped
永久删除匹配的记录
db.Unscoped().Delete(&order)
// DELETE FROM orders WHERE id=10;
事务