gorm


 連接初始

package main

import (
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

type Product struct {
	gorm.Model
	Code  string
	Price uint
}

func main() {
	db, err := gorm.Open("mysql", "root:123456@(192.168.188.128:3306)/gorm?charset=utf8&parseTime=True&loc=Local")
	if err != nil {
		panic("連接數據庫失敗")
	}
	defer db.Close()

	// 自動遷移模式,自動同步數據庫表
	db.AutoMigrate(&Product{})

	// 創建數據
	db.Create(&Product{
		Code:  "L1212",
		Price: 123,
	})
}

db結構體的方法

方法 說明 示例
NewRecord(value interface{})
 檢查傳入的參數的主鍵是否為空  
Create(value interface{})
 插入一條數據到數據庫,由於需要修改value的值,需要傳入地址  
db.Create(&product)
FirstOrCreate(out interface{}, where ...interface{})
 查詢,如果不存在就創建  
First(out interface{}, where ...interface{})

 獲取第一條數據,按照id排序

后面可以設置查詢條件

 
db.First(&user)
Last(out interface{}, where ...interface{})

 獲取最后一條數據,按照id排序

后面可以設置查詢條件

 
db.Last(&user)
Find(out interface{}, where ...interface{})

獲取所有的記錄

后面可以設置查詢條件

db.Find(&users)
db.Find(&products, "code = ?", "fdsf")
 
Where(query interface{}, args ...interface{})
 where條件查詢  
Not(query interface{}, args ...interface{})
 Not條件查詢  
Or(query interface{}, args ...interface{})
 Or條件查詢  
Order(value interface{}, reorder ...bool)
 排序  
Limit(limit interface{})
 指定要檢索的記錄數  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

使用db.Create可以創建一條數據

// 創建數據
db.Create(&Product{
    Code:  "L1212",
    Price: 123,
})

// 讀取
var product Product
db.First(&product, 1)    // 查找id為1的數據
db.First(&product, "code = ?", "L1212")   // 查找code=L1212的第一條數據

where查詢

// 獲取第一個匹配記錄
db.Where("name = ?", "jinzhu").First(&user)
//// SELECT * FROM users WHERE name = 'jinzhu' limit 1;

// 獲取所有匹配記錄
db.Where("name = ?", "jinzhu").Find(&users)
//// SELECT * FROM users WHERE name = 'jinzhu';

db.Where("name <> ?", "jinzhu").Find(&users)

// IN
db.Where("name in (?)", []string{"jinzhu", "jinzhu 2"}).Find(&users)

// LIKE
db.Where("name LIKE ?", "%jin%").Find(&users)

// AND
db.Where("name = ? AND age >= ?", "jinzhu", "22").Find(&users)

// Time
db.Where("updated_at > ?", lastWeek).Find(&users)

db.Where("created_at BETWEEN ? AND ?", lastWeek, today).Find(&users)

// Struct
db.Where(&User{Name: "jinzhu", Age: 20}).First(&user)
//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20 LIMIT 1;

// Map
db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users)
//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20;

// 主鍵的Slice
db.Where([]int64{20, 21, 22}).Find(&users)
//// SELECT * FROM users WHERE id IN (20, 21, 22);

Not查詢

db.Not("name", "jinzhu").First(&user)
//// SELECT * FROM users WHERE name <> "jinzhu" LIMIT 1;

// Not In
db.Not("name", []string{"jinzhu", "jinzhu 2"}).Find(&users)
//// SELECT * FROM users WHERE name NOT IN ("jinzhu", "jinzhu 2");

// Not In slice of primary keys
db.Not([]int64{1,2,3}).First(&user)
//// SELECT * FROM users WHERE id NOT IN (1,2,3);

db.Not([]int64{}).First(&user)
//// SELECT * FROM users;

// Plain SQL
db.Not("name = ?", "jinzhu").First(&user)
//// SELECT * FROM users WHERE NOT(name = "jinzhu");

// Struct
db.Not(User{Name: "jinzhu"}).First(&user)
//// SELECT * FROM users WHERE name <> "jinzhu";

Or查詢

db.Where("role = ?", "admin").Or("role = ?", "super_admin").Find(&users)
//// SELECT * FROM users WHERE role = 'admin' OR role = 'super_admin';

// Struct
db.Where("name = 'jinzhu'").Or(User{Name: "jinzhu 2"}).Find(&users)
//// SELECT * FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2';

// Map
db.Where("name = 'jinzhu'").Or(map[string]interface{}{"name": "jinzhu 2"}).Find(&users)

Select

指定要從數據庫查詢的列

db.Select("name, age").Find(&users)
//// SELECT name, age FROM users;

db.Select([]string{"name", "age"}).Find(&users)
//// SELECT name, age FROM users;

db.Table("users").Select("COALESCE(age,?)", 42).Rows()
//// SELECT COALESCE(age,'42') FROM users;

Order

在從數據庫檢索記錄時指定順序,將重排序設置為true以覆蓋定義的條件

db.Order("age desc, name").Find(&users)
//// SELECT * FROM users ORDER BY age desc, name;

// Multiple orders
db.Order("age desc").Order("name").Find(&users)
//// SELECT * FROM users ORDER BY age desc, name;

// ReOrder
db.Order("age desc").Find(&users1).Order("age", true).Find(&users2)
//// SELECT * FROM users ORDER BY age desc; (users1)
//// SELECT * FROM users ORDER BY age; (users2)

Limit

指定要檢索的記錄數

db.Limit(3).Find(&users)
//// SELECT * FROM users LIMIT 3;

// Cancel limit condition with -1
db.Limit(10).Find(&users1).Limit(-1).Find(&users2)
//// SELECT * FROM users LIMIT 10; (users1)
//// SELECT * FROM users; (users2)

Offset

指定在開始返回記錄之前要跳過的記錄數

db.Offset(3).Find(&users)
//// SELECT * FROM users OFFSET 3;

// Cancel offset condition with -1
db.Offset(10).Find(&users1).Offset(-1).Find(&users2)
//// SELECT * FROM users OFFSET 10; (users1)
//// SELECT * FROM users; (users2)

Count

獲取模型的記錄數

db.Where("name = ?", "jinzhu").Or("name = ?", "jinzhu 2").Find(&users).Count(&count)
//// SELECT * from USERS WHERE name = 'jinzhu' OR name = 'jinzhu 2'; (users)
//// SELECT count(*) FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2'; (count)

db.Model(&User{}).Where("name = ?", "jinzhu").Count(&count)
//// SELECT count(*) FROM users WHERE name = 'jinzhu'; (count)

db.Table("deleted_users").Count(&count)
//// SELECT count(*) FROM deleted_users;

Group & Having

rows, err := db.Table("orders").Select("date(created_at) as date, sum(amount) as total").Group("date(created_at)").Rows()
for rows.Next() {
    ...
}

rows, err := db.Table("orders").Select("date(created_at) as date, sum(amount) as total").Group("date(created_at)").Having("sum(amount) > ?", 100).Rows()
for rows.Next() {
    ...
}

type Result struct {
    Date  time.Time
    Total int64
}
db.Table("orders").Select("date(created_at) as date, sum(amount) as total").Group("date(created_at)").Having("sum(amount) > ?", 100).Scan(&results)

Join

指定連接條件

rows, err := db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Rows()
for rows.Next() {
    ...
}

db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Scan(&results)

// 多個連接與參數
db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzhu@example.org").Joins("JOIN credit_cards ON credit_cards.user_id = users.id").Where("credit_cards.number = ?", "411111111111").Find(&user)

Scan

將結果掃描到另一個結構中。

type Result struct {
    Name string
    Age  int
}

var result Result
db.Table("users").Select("name, age").Where("name = ?", 3).Scan(&result)

// Raw SQL
db.Raw("SELECT name, age FROM users WHERE name = ?", 3).Scan(&result)

// 更新
var product Product
db.First(&product, 1)    // 查找id為1的數據
db.Model(&product).Update("Price", 52000)   // 更新Price未52000

更新全部字段

db.First(&user)

user.Name = "jinzhu 2"
user.Age = 100
db.Save(&user)

//// UPDATE users SET name='jinzhu 2', age=100, birthday='2016-01-01', updated_at = '2013-11-17 21:34:10' WHERE id=111;

更新更改字段

如果只想更新更改的字段,可以使用UpdateUpdates

// 更新單個屬性(如果更改)
db.Model(&user).Update("name", "hello")
//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;

// 使用組合條件更新單個屬性
db.Model(&user).Where("active = ?", true).Update("name", "hello")
//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true;

// 使用`map`更新多個屬性,只會更新這些更改的字段
db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
//// UPDATE users SET name='hello', age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111;

// 使用`struct`更新多個屬性,只會更新這些更改的和非空白字段
db.Model(&user).Updates(User{Name: "hello", Age: 18})
//// UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111;

// 警告:當使用struct更新時,FORM將僅更新具有非空值的字段
// 對於下面的更新,什么都不會更新為"",0,false是其類型的空白值
db.Model(&user).Updates(User{Name: "", Age: 0, Actived: false})

更新選擇的字段

如果只想在更新時更新或忽略某些字段,可以使用SelectOmit

db.Model(&user).Select("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;

db.Model(&user).Omit("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
//// UPDATE users SET age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111;

Batch Updates 批量更新

db.Table("users").Where("id IN (?)", []int{10, 11}).Updates(map[string]interface{}{"name": "hello", "age": 18})
//// UPDATE users SET name='hello', age=18 WHERE id IN (10, 11);

// 使用struct更新僅適用於非零值,或使用map[string]interface{}
db.Model(User{}).Updates(User{Name: "hello", Age: 18})
//// UPDATE users SET name='hello', age=18;

// 使用`RowsAffected`獲取更新記錄計數
db.Model(User{}).Updates(User{Name: "hello", Age: 18}).RowsAffected

刪除

// 刪除
var product Product
db.First(&product, 1)    // 查找id為1的數據
db.Delete(&product)     // 刪除,只是軟刪除,會在DeleteAt添加時間

批量刪除

db.Where("email LIKE ?", "%jinzhu%").Delete(Email{})
//// DELETE from emails where email LIKE "%jinhu%";

db.Delete(Email{}, "email LIKE ?", "%jinzhu%")
//// DELETE from emails where email LIKE "%jinhu%";

軟刪除

如果模型有DeletedAt字段,它將自動獲得軟刪除功能! 那么在調用Delete時不會從數據庫中永久刪除,而是只將字段DeletedAt的值設置為當前時間。

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;

// 使用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;

模型

type User struct {
    gorm.Model
    Birthday     time.Time
    Age          int
    Name         string  `gorm:"size:255"`       // string默認長度為255, 使用這種tag重設。
    Num          int     `gorm:"AUTO_INCREMENT"` // 自增

    CreditCard        CreditCard      // One-To-One (擁有一個 - CreditCard表的UserID作外鍵)
    Emails            []Email         // One-To-Many (擁有多個 - Email表的UserID作外鍵)

    BillingAddress    Address         // One-To-One (屬於 - 本表的BillingAddressID作外鍵)
    BillingAddressID  sql.NullInt64

    ShippingAddress   Address         // One-To-One (屬於 - 本表的ShippingAddressID作外鍵)
    ShippingAddressID int

    IgnoreMe          int `gorm:"-"`   // 忽略這個字段
    Languages         []Language `gorm:"many2many:user_languages;"` // Many-To-Many , 'user_languages'是連接表
}

type Email struct {
    ID      int
    UserID  int     `gorm:"index"` // 外鍵 (屬於), tag `index`是為該列創建索引
    Email   string  `gorm:"type:varchar(100);unique_index"` // `type`設置sql類型, `unique_index` 為該列設置唯一索引
    Subscribed bool
}

type Address struct {
    ID       int
    Address1 string         `gorm:"not null;unique"` // 設置字段為非空並唯一
    Address2 string         `gorm:"type:varchar(100);unique"`
    Post     sql.NullString `gorm:"not null"`
}

type Language struct {
    ID   int
    Name string `gorm:"index:idx_name_code"` // 創建索引並命名,如果找到其他相同名稱的索引則創建組合索引
    Code string `gorm:"index:idx_name_code"` // `unique_index` also works
}

type CreditCard struct {
    gorm.Model
    UserID  uint
    Number  string
}

一對多

// 多的一方
type Profile struct {
  gorm.Model
  Name      string
  UserRefer uint      // 外鍵
}

// 一的一方
type User struct {
  gorm.Model
  Profiles []Profile `gorm:"ForeignKey:UserRefer"`      // 一個用戶包含多個介紹
}


db.Model(&user).Related(&profile)
//// SELECT * FROM profile WHERE user_id = 111; // 111 是 user 的主鍵

多對多

// User 包含並屬於多個 languages, 使用 `user_languages` 表連接
type User struct {
    gorm.Model
    Languages         []Language `gorm:"many2many:user_languages;"`
}

type Language struct {
    gorm.Model
    Name string
}

db.Model(&user).Related(&languages, "Languages")
//// SELECT * FROM "languages" INNER JOIN "user_languages" ON "user_languages"."language_id" = "languages"."id" WHERE "user_languages"."user_id" = 111

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM