1. 安裝
go get -u github.com/jinzhu/gorm
2.聲明module
type User struct {
gorm.Model
Name string
Age sql.NullInt64
Birthday *time.Time
Email string `gorm:"type:varchar(100);unique_index"`
Role string `gorm:"size:255"` // 設置屬性長度 255
MemberNumber *string `gorm:"unique;not null"` //設置唯一並且非空
Num int `gorm:"AUTO_INCREMENT"` //設置自增
Address string `gorm:"index:addr"` //給字段address創建索引,名’addr’
IgnoreMe int `gorm:"-"` // 忽略這個屬性
}
gorm.Model 包含如下屬性: ID, CreatedAt, UpdatedAt, DeletedAt.
// gorm.Model 定義
type Model struct {
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
}
GORM使用字段名為ID作為默認主鍵。
type User struct {
ID string
Name string
}
//設置AnimalID作為主鍵
type Animal struct {
AnimalID int64 `gorm:"primary_key"`
Name string
Age int64
}
在聲明模型時,tags是可選的。GORM支持以下tags。
**Tag** | **Description** |
---|---|
Column | Specifies column name |
Type | Specifies column data type |
Size | Specifies column size, default 255 |
PRIMARY_KEY | Specifies column as primary key |
UNIQUE | Specifies column as unique |
DEFAULT | Specifies column default value |
PRECISION | Specifies column precision |
NOT NULL | Specifies column as NOT NULL |
AUTO_INCREMENT | Specifies column auto incrementable or not |
INDEX | Create index with or without name, same name creates composite indexes |
UNIQUE_INDEX | Like INDEX, create unique index |
EMBEDDED | Set struct as embedded |
EMBEDDED_PREFIX | Set embedded struct’s prefix name |
- | Ignore this fields |
3. 關聯的結構標記
4.表名是結構體名稱的復數形式
type User struct {
}
其默認表名為users
可以設置表名為自定義名稱。
func (User) TableName() string {
return "profiles"
}
如果不想使用這個復數形式,可以設置為單數,傳true即可。
db.SingularTable(true)
也可以這樣定義:
db.Table("users").CreateTable(&User{})
使用user的結構創建表名為users。
5. 時間戳
CreatedAt
一條記錄第一次被創建的時候會修改該值。
// will set `CreatedAt` to current time
db.Create(&user)
// To change its value, you could use `Update`
db.Model(&user).Update("CreatedAt", time.Now())
UpdatedAt
當這條記錄被修改的時候,會修改該字段。
// will set `UpdatedAt` to current time
db.Save(&user)
// will set `UpdatedAt` to current time
db.Model(&user).Update("name", "jinzhu")
DeletedAt
對於具有deleted_at字段的模型,當對該實例調用Delete時,不會真正從數據庫中刪除它,而是將其DeletedAt字段設置為當前時間
6.連接數據庫
要連接到數據庫,需要先導入數據庫的驅動程序。
import _ ”github.com/go-sql-driver/mysql“
GORM包裝了一些驅動程序,以便更容易記住導入路徑。因此您可以使用以下命令導入mysql驅動程序:
import _ "github.com/jinzhu/gorm/dialects/mysql"
// import _ "github.com/jinzhu/gorm/dialects/postgres"
// import _ "github.com/jinzhu/gorm/dialects/sqlite"
// import _ "github.com/jinzhu/gorm/dialects/mssql"
下面主要講下MySQL
注意:
為了正確地處理time.time,需要將parseTime作為一個參數。
為了完全支持UTF-8編碼,需要將charset=utf8更改為charset=utf8mb4。
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
func main() {
db, err := gorm.Open("mysql", "user:password@(localhost)/dbname?charset=utf8&parseTime=True&loc=Local")
defer db.Close()
}
7. Create
user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()}
db.NewRecord(user) // => 當主鍵為空時返回true
db.Create(&user)
db.NewRecord(user) // => user創建后返回false
默認值:
type Animal struct {
ID int64
Name string `gorm:"default:'galeone'"`
Age int64
}
然后插入的SQL將排除那些沒有值或零的字段
var animal = Animal{Age: 99, Name: ""}
db.Create(&animal)
// INSERT INTO animals("age") values('99');
// SELECT name from animals WHERE ID=111; // the returning primary key is 111
// animal.Name => 'galeone'
注意:
所有具有零值的字段(如0、“”或其他零值)都不會保存到數據庫中,而是使用其默認值。如果要避免這種情況,請考慮使用指針類型
// Use pointer value
type User struct {
gorm.Model
Name string
Age *int `gorm:"default:18"`
}
// Use scanner/valuer
type User struct {
gorm.Model
Name string
Age sql.NullInt64 `gorm:"default:18"`
}
使用鈎子
如果要在BeforeCreate鈎子中更新字段的值,可以使用scope.SetColumn,例如:
func (user *User) BeforeCreate(scope *gorm.Scope) error {
scope.SetColumn("ID", uuid.New())
return nil
}
8. Query
// Get first record, order by primary key
db.First(&user)
//// SELECT * FROM users ORDER BY id LIMIT 1;
// Get one record, no specified order
db.Take(&user)
//// SELECT * FROM users LIMIT 1;
// Get last record, order by primary key
db.Last(&user)
//// SELECT * FROM users ORDER BY id DESC LIMIT 1;
// Get all records
db.Find(&users)
//// SELECT * FROM users;
// Get record with primary key (only works for integer primary key)
db.First(&user, 10)
//// SELECT * FROM users WHERE id = 10;
9. Where
原始sql
// Get first matched record
db.Where("name = ?", "jinzhu").First(&user)
//// SELECT * FROM users WHERE name = 'jinzhu' ORDER BY id LIMIT 1;
// Get all matched records
db.Where("name = ?", "jinzhu").Find(&users)
//// SELECT * FROM users WHERE name = 'jinzhu';
// <>
db.Where("name <> ?", "jinzhu").Find(&users)
//// SELECT * FROM users WHERE name <> 'jinzhu';
// IN
db.Where("name IN (?)", []string{"jinzhu", "jinzhu 2"}).Find(&users)
//// SELECT * FROM users WHERE name in ('jinzhu','jinzhu 2');
// LIKE
db.Where("name LIKE ?", "%jin%").Find(&users)
//// SELECT * FROM users WHERE name LIKE '%jin%';
// AND
db.Where("name = ? AND age >= ?", "jinzhu", "22").Find(&users)
//// SELECT * FROM users WHERE name = 'jinzhu' AND age >= 22;
// Time
db.Where("updated_at > ?", lastWeek).Find(&users)
//// SELECT * FROM users WHERE updated_at > '2000-01-01 00:00:00';
// BETWEEN
db.Where("created_at BETWEEN ? AND ?", lastWeek, today).Find(&users)
//// SELECT * FROM users WHERE created_at BETWEEN '2000-01-01 00:00:00' AND '2000-01-08 00:00:00';
10. Struct & Map
// Struct
db.Where(&User{Name: "jinzhu", Age: 20}).First(&user)
//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20 ORDER BY id LIMIT 1;
// Map
db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users)
//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20;
// Slice of primary keys
db.Where([]int64{20, 21, 22}).Find(&users)
//// SELECT * FROM users WHERE id IN (20, 21, 22);
注意:
當使用struct進行查詢時,GORM將只使用那些字段具有非零值的查詢,這意味着如果字段的值為0、’’、false或其他零值,則不會使用它來構建查詢條件,例如:
db.Where(&User{Name: "jinzhu", Age: 0}).Find(&users)
//// SELECT * FROM users WHERE name = "jinzhu";
11. 添加額外查詢項
db.Set("gorm:query_option", "FOR UPDATE").First(&user, 10)
//// SELECT * FROM users WHERE id = 10 FOR UPDATE;
12. FirstOrInit
獲取第一個匹配的記錄,或使用給定條件初始化新記錄(僅適用於結構、map)
// Unfound
db.FirstOrInit(&user, User{Name: "non_existing"})
//// user -> User{Name: "non_existing"}
// Found
db.Where(User{Name: "Jinzhu"}).FirstOrInit(&user)
//// user -> User{Id: 111, Name: "Jinzhu", Age: 20}
db.FirstOrInit(&user, map[string]interface{}{"name": "jinzhu"})
//// user -> User{Id: 111, Name: "Jinzhu", Age: 20}
13. Attrs
如果找不到記錄,則使用參數初始化結構
// Unfound
db.Where(User{Name: "non_existing"}).Attrs(User{Age: 20}).FirstOrInit(&user)
//// SELECT * FROM USERS WHERE name = 'non_existing' ORDER BY id LIMIT 1;
//// user -> User{Name: "non_existing", Age: 20}
db.Where(User{Name: "non_existing"}).Attrs("age", 20).FirstOrInit(&user)
//// SELECT * FROM USERS WHERE name = 'non_existing' ORDER BY id LIMIT 1;
//// user -> User{Name: "non_existing", Age: 20}
// Found
db.Where(User{Name: "Jinzhu"}).Attrs(User{Age: 30}).FirstOrInit(&user)
//// SELECT * FROM USERS WHERE name = jinzhu' ORDER BY id LIMIT 1;
//// user -> User{Id: 111, Name: "Jinzhu", Age: 20}
14. Assign
將參數賦給結構,不管是否找到它。
// Unfound
db.Where(User{Name: "non_existing"}).Assign(User{Age: 20}).FirstOrInit(&user)
//// user -> User{Name: "non_existing", Age: 20}
// Found
db.Where(User{Name: "Jinzhu"}).Assign(User{Age: 30}).FirstOrInit(&user)
//// SELECT * FROM USERS WHERE name = jinzhu' ORDER BY id LIMIT 1;
//// user -> User{Id: 111, Name: "Jinzhu", Age: 30}
15. FirstOrCreate
獲取第一個匹配的記錄,或使用給定條件創建一個新記錄(僅適用於結構、映射條件)。
// Unfound
db.FirstOrCreate(&user, User{Name: "non_existing"})
//// INSERT INTO "users" (name) VALUES ("non_existing");
//// user -> User{Id: 112, Name: "non_existing"}
// Found
db.Where(User{Name: "Jinzhu"}).FirstOrCreate(&user)
//// user -> User{Id: 111, Name: "Jinzhu"}
16.高級查詢
SubQuery
db.Where("amount > ?", db.Table("orders").Select("AVG(amount)").Where("state = ?", "paid").SubQuery()).Find(&orders)
// SELECT * FROM "orders" WHERE "orders"."deleted_at" IS NULL AND (amount > (SELECT AVG(amount) FROM "orders" WHERE (state = 'paid')));
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
指定從數據庫檢索記錄時的順序,將reorder(第二個參數)設置為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;
db.Table("deleted_users").Select("count(distinct(name))").Count(&count)
//// SELECT count( distinct(name) ) FROM deleted_users; (count)
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)
Joins
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)
// multiple joins with parameter
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)
Pluck
將模型中的單個列作為映射查詢,如果要查詢多個列,則應改用Scan。
var ages []int64
db.Find(&users).Pluck("age", &ages)
var names []string
db.Model(&User{}).Pluck("name", &names)
db.Table("deleted_users").Pluck("name", &names)
// Requesting more than one column? Do it like this:
db.Select("name, age").Find(&users)
Scan
將結果掃描到另一個結構中。
type Result struct {
Name string
Age int
}
var result Result
db.Table("users").Select("name, age").Where("name = ?", "Antonio").Scan(&result)
// Raw SQL
db.Raw("SELECT name, age FROM users WHERE name = ?", "Antonio").Scan(&result)
Update
修改所有屬性。Save將在執行更新SQL時包含所有字段,即使沒有更改。
db.First(&user)
user.Name = "jinzhu2"
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;
更新更改的字段
如果只想更新已更改的字段,可以使用update,Updates。
// Update single attribute if it is changed
db.Model(&user).Update("name", "hello")
//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;
// Update single attribute with combined conditions
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;
// Update multiple attributes with `map`, will only update those changed fields
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;
// Update multiple attributes with `struct`, will only update those changed & non blank fields
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;
// WARNING when update with struct, GORM will only update those fields that with non blank value
// For below Update, nothing will be updated as "", 0, false are blank values of their types
db.Model(&user).Updates(User{Name: "", Age: 0, Actived: false})
修改列不用鈎子
以上更新操作將執行模型的BeforeUpdate、AfterUpdate方法,更新其UpdatedAt時間戳,更新時保存其關聯,如果不想調用它們,可以使用UpdateColumn、UpdateColumns。
// Update single attribute, similar with `Update`
db.Model(&user).UpdateColumn("name", "hello")
//// UPDATE users SET name='hello' WHERE id = 111;
// Update multiple attributes, similar with `Updates`
db.Model(&user).UpdateColumns(User{Name: "hello", Age: 18})
//// UPDATE users SET name='hello', age=18 WHERE id = 111;
批量修改
批量更新時不會運行鈎子。
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);
// Update with struct only works with none zero values, or use map[string]interface{}
db.Model(User{}).Updates(User{Name: "hello", Age: 18})
//// UPDATE users SET name='hello', age=18;
// Get updated records count with `RowsAffected`
db.Model(User{}).Updates(User{Name: "hello", Age: 18}).RowsAffected
使用 SQL **表達式
DB.Model(&product).Update("price", gorm.Expr("price * ? + ?", 2, 100))
//// UPDATE "products" SET "price" = price * '2' + '100', "updated_at" = '2013-11-17 21:34:10' WHERE "id" = '2';
DB.Model(&product).Updates(map[string]interface{}{"price": gorm.Expr("price * ? + ?", 2, 100)})
//// UPDATE "products" SET "price" = price * '2' + '100', "updated_at" = '2013-11-17 21:34:10' WHERE "id" = '2';
DB.Model(&product).UpdateColumn("quantity", gorm.Expr("quantity - ?", 1))
//// UPDATE "products" SET "quantity" = quantity - 1 WHERE "id" = '2';
DB.Model(&product).Where("quantity > 1").UpdateColumn("quantity", gorm.Expr("quantity - ?", 1))
//// UPDATE "products" SET "quantity" = quantity - 1 WHERE "id" = '2' AND quantity > 1;
使用鈎子更改值
如果要使用BeforeUpdate、BeforeSave更改掛鈎中的更新值,可以使用scope.SetColumn,例如:
func (user *User) BeforeSave(scope *gorm.Scope) (err error) {
if pw, err := bcrypt.GenerateFromPassword(user.Password, 0); err == nil {
scope.SetColumn("EncryptedPassword", pw)
}
}
Delete
如果一個模型有一個DeletedAt字段,它將自動獲得一個軟刪除能力!調用Delete時,不會從數據庫中永久刪除記錄;相反,DeletedAt的值將設置為當前時間。
db.Delete(&user)
//// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE id = 111;
// Batch Delete
db.Where("age = ?", 20).Delete(&User{})
//// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE age = 20;
// Soft deleted records will be ignored when query them
db.Where("age = 20").Find(&user)
//// SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL;
// Find soft deleted records with Unscoped
db.Unscoped().Where("age = 20").Find(&users)
//// SELECT * FROM users WHERE age = 20;
永久刪除記錄
// Delete record permanently with Unscoped
db.Unscoped().Delete(&order)
//// DELETE FROM orders WHERE id=10;
Belongs To
歸屬於關聯與另一個模型建立一對一的連接,這樣聲明模型的每個實例都“屬於”另一個模型的一個實例。
例如,如果應用程序包含用戶和配置文件,並且每個配置文件都可以指定給一個用戶。
type User struct {
gorm.Model
Name string
}
// `Profile` belongs to `User`, `UserID` is the foreign key
type Profile struct {
gorm.Model
UserID int
User User
Name string
}
外鍵
若要定義“屬於”關系,外鍵必須存在,默認外鍵使用所有者的類型名及其主鍵。
對於上面的示例,要定義屬於用戶的模型,外鍵應該是UserID。
GORM提供了一種自定義外鍵的方法,例如:
type User struct {
gorm.Model
Name string
}
type Profile struct {
gorm.Model
Name string
User User `gorm:"foreignkey:UserRefer"` // use UserRefer as foreign key
UserRefer uint
}
關聯外鍵
對於歸屬關系,GORM通常使用所有者的主鍵作為外鍵的值,例如,它是用戶的ID。
將配置文件分配給用戶時,GORM會將用戶的ID保存到配置文件的UserID字段中。可以使用標記關聯外鍵進行更改,例如:
type User struct {
gorm.Model
Refer string
Name string
}
type Profile struct {
gorm.Model
Name string
User User `gorm:"association_foreignkey:Refer"` // use Refer as association foreign key
UserRefer string
}
使用 belong to
db.Model(&user).Related(&profile)
//// SELECT * FROM profiles WHERE user_id = 111; // 111 is user's ID
ManyToMany
**Foreign Keys
type CustomizePerson struct {
IdPerson string `gorm:"primary_key:true"`
Accounts []CustomizeAccount `gorm:"many2many:PersonAccount;association_foreignkey:idAccount;foreignkey:idPerson"`
}
type CustomizeAccount struct {
IdAccount string `gorm:"primary_key:true"`
Name string
}
它將為這兩個結構創建多個關系,並將它們的關系保存到聯接表personAccount帶有外鍵的customize_person_id_person和customize_account。
Jointable ForeignKey
如果要更改聯接表的外鍵,可以使用標記關聯。
type CustomizePerson struct {
IdPerson string `gorm:"primary_key:true"`
Accounts []CustomizeAccount `gorm:"many2many:PersonAccount;foreignkey:idPerson;association_foreignkey:idAccount;association_jointable_foreignkey:account_id;jointable_foreignkey:person_id;"`
}
type CustomizeAccount struct {
IdAccount string `gorm:"primary_key:true"`
Name string
}
Self-Referencing
要定義自引用的many2many關系,必須在聯接表中更改關聯的外鍵。要使其與使用結構名稱及其主鍵生成的源外鍵不同,例如:
type People struct {
gorm.Model
Friends []*People `gorm:"many2many:friendships;association_jointable_foreignkey:friend_id"`
}
GORM將創建一個具有外鍵people_id和friend_id的聯接表,並使用它保存用戶的自引用關系。
17. 錯誤處理
Error Handling
GORM中的錯誤處理不同於慣用的Go代碼,因為它的API是可鏈接的,但是仍然易於實現。
如果發生任何錯誤,GORM將設置*GORM.DB的錯誤字段,可以這樣檢查:
f err := db.Where("name = ?", "jinzhu").First(&user).Error; err != nil {
// error handling...
}
RecordNotFound Error
GORM提供了處理RecordNotFound錯誤的快捷方式。如果有幾個錯誤,它將檢查其中是否有一個是RecordNotFound錯誤。
// Check if returns RecordNotFound error
db.Where("name = ?", "hello world").First(&user).RecordNotFound()
if db.Model(&user).Related(&credit_card).RecordNotFound() {
// record not found
}
if err := db.Where("name = ?", "jinzhu").First(&user).Error; gorm.IsRecordNotFoundError(err) {
// record not found
}
18 事務
GORM默認情況下在事務中執行單個創建、更新、刪除操作,以確保數據庫數據的完整性。如果要將多個create、update、delete視為一個原子操作,則為此進行事務處理。
func CreateAnimals(db *gorm.DB) error {
return db.Transaction(func(tx *gorm.DB) error {
// do some database operations in the transaction (use 'tx' from this point, not 'db')
if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
// return any error will rollback
return err
}
if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
return err
}
// return nil will commit
return nil
})
}
19. Migration
自動遷移架構,使架構保持最新。
注意:自動遷移將只創建表、缺少列和缺少索引,並且不會更改現有列的類型或刪除未使用的列以保護數據。
db.AutoMigrate(&User{})
db.AutoMigrate(&User{}, &Product{}, &Order{})
// Add table suffix when create tables
db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&User{})
20. Schema Methods
判斷表是否存在。
// Check model `User`'s table exists or not
db.HasTable(&User{})
// Check table `users` exists or not
db.HasTable("users")
創建表。
// Create table for model `User`
db.CreateTable(&User{})
// will append "ENGINE=InnoDB" to the SQL statement when creating table `users`
db.Set("gorm:table_options", "ENGINE=InnoDB").CreateTable(&User{})
刪除表。
// Drop model `User`'s table
db.DropTable(&User{})
// Drop table `users`
db.DropTable("users")
// Drop model's `User`'s table and table `products`
db.DropTableIfExists(&User{}, "products")
修改列。
// change column description's data type to `text` for model `User`
db.Model(&User{}).ModifyColumn("description", "text")
添加索引。
// Add index for columns `name` with given name `idx_user_name`
db.Model(&User{}).AddIndex("idx_user_name", "name")
// Add index for columns `name`, `age` with given name `idx_user_name_age`
db.Model(&User{}).AddIndex("idx_user_name_age", "name", "age")
// Add unique index
db.Model(&User{}).AddUniqueIndex("idx_user_name", "name")
// Add unique index for multiple columns
db.Model(&User{}).AddUniqueIndex("idx_user_name_age", "name", "age")
刪除索引。
// Remove index
db.Model(&User{}).RemoveIndex("idx_user_name")
復合主鍵。
將多個字段設置為主鍵以啟用復合主鍵。
type Product struct {
ID string `gorm:"primary_key"`
LanguageCode string `gorm:"primary_key"`
Code string
Name string
}
注意,帶有primary_key標記的整數字段在默認情況下是自動遞增的。這可能導致多個自動遞增的整數主鍵,而不是單個復合主鍵。
要創建包含int的復合主鍵,需要關閉int字段的自動遞增:
type Product struct {
CategoryID uint64 `gorm:"primary_key;auto_increment:false"`
TypeID uint64 `gorm:"primary_key;auto_increment:false"`
}