Golang - Mysql操作

一、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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章