一、gorm增刪改查
1、示例代碼:
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"time"
)
/**
CREATE TABLE `t_user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`age` tinyint(3) unsigned NOT NULL DEFAULT 1,
`addtime` datetime NOT NULL,
`updtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_unique_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
*/
type User struct {
ID uint `gorm:"column:id;type:int(10) unsigned AUTO_INCREMENT;not null;primary_key"`
Name string `gorm:"column:name;type:varchar(100);not null;unique_index:idx_unique_name"`
Age uint `gorm:"column:age;type:tinyint(3) unsigned;not null;default:1"`
CreatedAt time.Time `gorm:"column:addtime;type:datetime;not null"`
UpdatedAt time.Time `gorm:"column:updtime;type:timestamp;not null;default:CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"`
}
func (u *User) TableName() string {
return "t_user"
}
func main() {
db, err := gorm.Open("mysql", "root:root@tcp(127.0.0.1:3306)/p_test?charset=utf8&parseTime=True&loc=Local")
if err != nil {
fmt.Println(err)
return
}
defer db.Close()
db.DB().SetMaxIdleConns(1)
db.DB().SetMaxOpenConns(10)
db.DB().SetConnMaxLifetime(10 * time.Minute)
db.LogMode(true)
// 刪除表
if db.HasTable(&User{}) {
db.DropTable(&User{})
}
// 創建表
db.Set("gorm:table_options", "ENGINE=InnoDB DEFAULT CHARSET=utf8").CreateTable(&User{})
// 添加數據
users := []*User{
{Name: "yan.wang1", Age: 18},
{Name: "yan.wang2", Age: 19},
{Name: "yan.wang3", Age: 20},
}
for _, user := range users {
db.Create(user)
}
// 查詢數據
users = make([]*User, 0, 10)
query := db.Order("id desc").Find(&users, "age > ?", 18)
if err := query.Error; err != nil {
fmt.Println(err)
return
}
// 更新數據
query = db.Model(&User{}).Where(&User{Name: "yan.wang1"}).Update(&User{Age: 21})
if err := query.Error; err != nil {
fmt.Println(err)
return
}
// 刪除數據
query = db.Delete(&User{}, "name = ?", "yan.wang1")
if err := query.Error; err != nil {
fmt.Println(err)
return
}
}
2、插入數據
- NewRecord 僅僅檢測user的主鍵是否爲空
- Create,傳入user的指針
- 若插入成功,Insert語句返回的主鍵ID會賦值給user,再檢測NewRecord則爲false
- Create 可以換成Save,Save會檢測user的主鍵是否爲空,爲空就create,否則update
user := User{Name: "yan.wang5", Age: 23}
fmt.Printf("check user primary key empty: %#v\n", db.NewRecord(user))
db.Create(&user)
fmt.Printf("check user primary key empty: %#v\n", db.NewRecord(user))
fmt.Printf("print user after create: %#v\n", user)
3、更新數據
- 查詢出來的數據,有主鍵ID的,可以直接使用Save進行更新
var user User
db.First(&user)
user.Name = "yan.wang6"
user.Age = 11
db.Save(&user)
- 一共四種更新方式,可以使用Expr自定義更新sql語句
- 如果不想更新時間字段,即不調用callback函數,請使用UpdateColumn(s)替代update
query := db.Model(&User{}).Where("name = ?", "yan.wang3")
// UPDATE `t_user` SET `age` = 20, `updtime` = '2019-12-01 16:53:27' WHERE (name = 'yan.wang3')
query.Update("age", 20)
// UPDATE `t_user` SET `age` = age + 5, `updtime` = '2019-12-01 16:53:27' WHERE (name = 'yan.wang3')
query.Update("age", gorm.Expr("age + 5"))
// UPDATE `t_user` SET `age` = 25, `updtime` = '2019-12-01 16:53:27' WHERE (name = 'yan.wang3')
query.Update(&User{Age: 25})
// UPDATE `t_user` SET `age` = age + 10, `updtime` = '2019-12-01 16:53:27' WHERE (name = 'yan.wang3')
query.Update(map[string]interface{}{"age": gorm.Expr("age + 10")})
// Do nothing
query.Update(&User{Age: 0})
4、刪除數據
// DELETE FROM `t_user` WHERE `t_user`.`id` = 2
db.Delete(&User{ID: 2})
// DELETE FROM `t_user` WHERE (name = 'yan.wang5')
db.Delete(&User{}, "name = ?", "yan.wang5")
// DELETE FROM `t_user` WHERE (name = 'yan.wang5')
db.Where("name = ?", "yan.wang5").Delete(&User{})
5、查詢數據
1、使用 Where
- 查詢單條數據,沒有查詢到,請調用RecordNotFound,該方法 僅支持單條
var user User
// SELECT * FROM `t_user` ORDER BY `t_user`.`id` ASC LIMIT 1
db.First(&user)
// SELECT * FROM `t_user` ORDER BY `t_user`.`id` DESC LIMIT 1
db.Last(&user)
- 查詢所有數據,使用時,請檢查是否帶上條件,否則不要使用
var user []*User
// SELECT * FROM `t_user`
db.Find(&user)
- 主鍵查詢的三種典型方式
var user User
// SELECT * FROM `t_user` WHERE (`t_user`.`id` = 3) ORDER BY `t_user`.`id` ASC LIMIT 1
db.First(&user, 3)
// SELECT * FROM `t_user` WHERE `t_user`.`id` = 3 ORDER BY `t_user`.`id` ASC LIMIT 1
user.ID = 3
db.First(&user)
// SELECT * FROM `t_user` WHERE (`t_user`.`id` = 3) ORDER BY `t_user`.`id` ASC LIMIT 1
db.Where(3).First(&user)
- 使用簡單的sql語句進行查詢
var user User
// SELECT * FROM `t_user` WHERE (name = 'yan.wang5') ORDER BY `t_user`.`id` ASC LIMIT 1
db.Where("name = ?", "yan.wang5").First(&user)
// SELECT * FROM `t_user` WHERE (name like 'yan.wang%') ORDER BY `t_user`.`id` ASC LIMIT 1
db.Where("name like ?", "yan.wang%").First(&user)
// SELECT * FROM `t_user` WHERE (name <> 'yan.wang6') ORDER BY `t_user`.`id` ASC LIMIT 1
db.Where("name <> ?", "yan.wang6").First(&user)
// SELECT * FROM `t_user` WHERE (age between 10 and 20) ORDER BY `t_user`.`id` ASC LIMIT 1
db.Where("age between ? and ?", 10, 20).First(&user)
// SELECT * FROM `t_user` WHERE (age IN (10,20)) ORDER BY `t_user`.`id` ASC LIMIT 1
db.Where("age IN (?)", []int{10, 20}).First(&user)
- 使用struct和map進行查詢
var user User
// SELECT * FROM `t_user` WHERE (`t_user`.`id` = 3) ORDER BY `t_user`.`id` ASC LIMIT 1
db.Where(&User{ID: 3}).First(&user)
// SELECT * FROM `t_user` WHERE (`t_user`.`name` = 'yan.wang5') ORDER BY `t_user`.`id` ASC LIMIT 1
db.Where(map[string]interface{}{"name": "yan.wang5"}).First(&user)
- 簡單的查詢,可以不使用Where
var user User
// SELECT * FROM `t_user` WHERE (name = 'yan.wang5') ORDER BY `t_user`.`id` ASC LIMIT 1
db.First(&user, "name = ?", "yan.wang5")
- 附加額外的查詢鎖
var user User
// SELECT * FROM `t_user` WHERE (`t_user`.`id` = 3) ORDER BY `t_user`.`id` ASC LIMIT 1 FOR UPDATE
db.Set("gorm:query_option", "FOR UPDATE").First(&user, 3)
// SELECT * FROM `t_user` WHERE `t_user`.`id` = 3 AND ((`t_user`.`id` = 3)) ORDER BY `t_user`.`id` ASC LIMIT 1 LOCK IN SHARE MODE
db.Set("gorm:query_option", "LOCK IN SHARE MODE").First(&user, 3)
2、其他查詢函數
- 關於查詢字段,排序,偏移,分組等操作
var user []*User
// SELECT name, age FROM `t_user` GROUP BY age HAVING (name like 'yan.wang%')
// ORDER BY name desc LIMIT 10 OFFSET 0
query := db.Select([]string{"name", "age"})
query = query.Order("name desc")
query = query.Offset(0).Limit(10)
query = query.Group("age").Having("name like ?", "yan.wang%")
query = query.Find(&user)
- join操作
var user []*User
// SELECT u1.* FROM t_user AS u1 LEFT JOIN t_user u2 ON u2.age = u1.age
db.Table("t_user AS u1").Select("u1.*").Joins("LEFT JOIN t_user u2 ON u2.age = u1.age").Find(&user)
- Pluck操作(不建議使用,反射性能不好,建議自己循環取值)
var names []string
// SELECT name FROM `t_user`
db.Model(&User{}).Pluck("name", &names)
fmt.Println(names)
- Scan操作
type NA struct {
Name string
AAA uint `gorm:"column:age"`
}
var na []NA
// SELECT name, age FROM `t_user`
db.Model(&User{}).Select("name, age").Scan(&na)
- Scopes操作
var age20 = func(db *gorm.DB) *gorm.DB {
return db.Where("age = ?", 20)
}
var name5 = func(db *gorm.DB) *gorm.DB {
return db.Where("name = ?", "yan.wang5")
}
var user []*User
// SELECT * FROM `t_user` WHERE (age = 20) AND (name = 'yan.wang5')
db.Scopes(age20, name5).Find(&user)