目錄
- Gorm Model
- 模型定義示例
- 結構體標記(tags)
- 支持的結構體標記(Struct tags)
- 關聯相關標記(tags)
- 例子
- 主鍵、表名、列名的約定
- 主鍵(Primary Key)
- 表名(Table name)
- 列名
- 時間戳跟蹤
Gorm Model
在使用ORM工具時,通常我們需要在代碼中定義模型(Models)與資料庫中的資料表進行映射,在GORM中模型(Models)通常是正常定義的結構體、基本的go型別或它們的指標,同時也支持sql.Scanner(掃描)及driver.Valuer(驅動)介面(interfaces)
為了方便模型定義,GORM內置了一個gorm.Model結構體,gorm.Model是一個包含了ID, CreatedAt, UpdatedAt, DeletedAt四個欄位的Golang結構體,
// gorm.Model 定義
type Model struct {
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
}
可以將它嵌入到自己的模型中:
// 將 `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`欄位注入到`User`模型中
type User struct {
gorm.Model
Name string
}
也可以完全自己定義模型:
// 不使用gorm.Model,自行定義模型
type User struct {
ID int
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
Name string
}
模型定義示例
//定義模型
type User struct {
gorm.Model //內嵌gorm.Model
Name string //名字
Age sql.NullInt64 //年齡 零值型別
Birthday *time.Time
Email string `gorm:"type:varchar(100);unique_index"` //結構體的tag
Role string `gorm:"size:255"` // 設定欄位大小為255
MemberNumber *string `gorm:"unique;not null"` // 設定會員號(member number)唯一并且不為空
Num int `gorm:"AUTO_INCREMENT"` // 設定 num 為自增型別
Address string `gorm:"index:addr"` // 給address欄位創建名為addr的索引
IgnoreMe int `gorm:"-"` // 忽略本欄位
}
結構體標記(tags)
使用結構體宣告模型時,標記(tags)是可選項,gorm支持以下標記:
支持的結構體標記(Struct tags)
| 結構體標記(Tag) | 描述 |
|---|---|
| Column | 指定列名 |
| Type | 指定列資料型別 |
| Size | 指定列大小, 默認值255 |
| PRIMARY_KEY | 將列指定為主鍵 |
| UNIQUE | 將列指定為唯一 |
| DEFAULT | 指定列默認值 |
| PRECISION | 指定列精度 |
| NOT NULL | 將列指定為非 NULL |
| AUTO_INCREMENT | 指定列是否為自增型別 |
| INDEX | 創建具有或不帶名稱的索引, 如果多個索引同名則創建復合索引 |
| UNIQUE_INDEX | 和 INDEX 類似,只不過創建的是唯一索引 |
| EMBEDDED | 將結構設定為嵌入 |
| EMBEDDED_PREFIX | 設定嵌入結構的前綴 |
| - | 忽略此欄位 |
關聯相關標記(tags)
| 結構體標記(Tag) | 描述 |
|---|---|
| MANY2MANY | 指定連接表 |
| FOREIGNKEY | 設定外鍵 |
| ASSOCIATION_FOREIGNKEY | 設定關聯外鍵 |
| POLYMORPHIC | 指定多型型別 |
| POLYMORPHIC_VALUE | 指定多型值 |
| JOINTABLE_FOREIGNKEY | 指定連接表的外鍵 |
| ASSOCIATION_JOINTABLE_FOREIGNKEY | 指定連接表的關聯外鍵 |
| SAVE_ASSOCIATIONS | 是否自動完成 save 的相關操作 |
| ASSOCIATION_AUTOUPDATE | 是否自動完成 update 的相關操作 |
| ASSOCIATION_AUTOCREATE | 是否自動完成 create 的相關操作 |
| ASSOCIATION_SAVE_REFERENCE | 是否自動完成參考的 save 的相關操作 |
| PRELOAD | 是否自動完成預加載的相關操作 |
例子
package main
import (
"database/sql"
"github.com/jinzhu/gorm"
_"github.com/jinzhu/gorm/dialects/mysql"
"time"
)
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"` // 設定會員號(member number)唯一并且不為空
Num int `gorm:"AUTO_INCREMENT"` // 設定 num 為自增型別
Address string `gorm:"index:addr"` // 給address欄位創建名為addr的索引
IgnoreMe int `gorm:"-"` // 忽略本欄位
}
func main() {
db, err := gorm.Open("mysql","root:123456@tcp(127.0.0.1:3306)/db?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.AutoMigrate(&User{})
}

主鍵、表名、列名的約定
主鍵(Primary Key)
GORM 默認會使用名為ID的欄位作為表的主鍵,

自定義主鍵
// 使用`AnimalID`作為主鍵
type Animal struct {
AnimalID int64 `gorm:"primary_key"`
Name string
Age int64
}
func main() {
db, err := gorm.Open("mysql","root:123456@tcp(127.0.0.1:3306)/db?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.AutoMigrate(&Animal{})
}

表名(Table name)
表名默認就是結構體名稱的復數
// 使用`AnimalID`作為主鍵
type Animal struct {
AnimalID int64 `gorm:"primary_key"`
Name string
Age int64
}
//表名 紫色飛豬
func (Animal) TableName()string {
return "zisefeizhu"
}
func main() {
db, err := gorm.Open("mysql","root:123456@tcp(127.0.0.1:3306)/db?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.AutoMigrate(&Animal{}) //重新建了一個表 不會洗掉
}

表名判斷
import (
"database/sql"
"github.com/jinzhu/gorm"
_"github.com/jinzhu/gorm/dialects/mysql"
"time"
)
// 使用`AnimalID`作為主鍵
type Animal struct {
AnimalID int64 `gorm:"primary_key"`
Name string
Age int64
}
//表名 紫色飛豬
//func (Animal) TableName()string {
//return "zisefeizhu"
//}
func (a Animal) TableName() string {
if a.Name == "admin" {
return "admin_animal"
} else {
return "zisefeizhu"
}
}
func main() {
db, err := gorm.Open("mysql","root:123456@tcp(127.0.0.1:3306)/db?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
animal := Animal{
AnimalID:1,
Name: "admin",
Age: 22,
}
db.AutoMigrate(&animal)
}

洗掉表名:drop table biaoming;
表名禁用復數
import (
"database/sql"
"github.com/jinzhu/gorm"
_"github.com/jinzhu/gorm/dialects/mysql"
"time"
)
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"` // 設定會員號(member number)唯一并且不為空
Num int `gorm:"AUTO_INCREMENT"` // 設定 num 為自增型別
Address string `gorm:"index:addr"` // 給address欄位創建名為addr的索引
IgnoreMe int `gorm:"-"` // 忽略本欄位
}
// 使用`AnimalID`作為主鍵
type Animal struct {
AnimalID int64 `gorm:"primary_key"`
Name string
Age int64
}
func main() {
db, err := gorm.Open("mysql","root:123456@tcp(127.0.0.1:3306)/db?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.SingularTable(true) // 禁用默認表名的復數形式,如果置為 true,則 `User` 的默認表名是 `user`
db.AutoMigrate(&User{})
db.AutoMigrate(&Animal{})
}

自定義表名
//使用User結構體創建名為zisefeizhu的表
//db.Table("zisefeizhu").CreateTable(&User{}) //表明最好有意義
var deleted_users []User
db.Table("deleted_users").Find(&deleted_users)
//// SELECT * FROM deleted_users;
db.Table("deleted_users").Where("name = ?", "jinzhu").Delete()
//// DELETE FROM deleted_users WHERE name = 'jinzhu';
GORM還支持更改默認表名稱規則:
? 建立一個專案,命名加一個統一的前綴
func main() {
//修改默認的表明規則
gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string {
return "zisefeizhu_" + defaultTableName;
}

列名
列名由欄位名稱進行下劃線分割來生成
type User struct {
ID uint // column name is `id`
Name string // column name is `name`
Birthday time.Time // column name is `birthday`
CreatedAt time.Time // column name is `created_at`
}
可以使用結構體tag指定列名:
type Animal struct {
AnimalId int64 `gorm:"column:beast_id"` // set column name to `beast_id`
Birthday time.Time `gorm:"column:day_of_the_beast"` // set column name to `day_of_the_beast`
Age int64 `gorm:"column:age_of_the_beast"` // set column name to `age_of_the_beast`
}
例子
import (
"database/sql"
"github.com/jinzhu/gorm"
_"github.com/jinzhu/gorm/dialects/mysql"
"time"
)
type User struct {
gorm.Model
Name string
Age sql.NullInt64 `gorm:"column:age_of_the_beast"`
Birthday *time.Time
Email string `gorm:"type:varchar(100);unique_index"`
Role string `gorm:"size:255"` // 設定欄位大小為255
MemberNumber *string `gorm:"unique;not null"` // 設定會員號(member number)唯一并且不為空
Num int `gorm:"AUTO_INCREMENT"` // 設定 num 為自增型別
Address string `gorm:"index:addr"` // 給address欄位創建名為addr的索引
IgnoreMe int `gorm:"-"` // 忽略本欄位
}
func main() {
//修改默認的表明規則
gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string {
return "zisefeizhu_" + defaultTableName;
}
db, err := gorm.Open("mysql","root:123456@tcp(127.0.0.1:3306)/db?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.SingularTable(true) // 禁用默認表名的復數形式,如果置為 true,則 `User` 的默認表名是 `user`
db.AutoMigrate(&User{})
}

時間戳跟蹤
CreatedAt
如果模型有 CreatedAt欄位,該欄位的值將會是初次創建記錄的時間,
db.Create(&user) // `CreatedAt`將會是當前時間
// 可以使用`Update`方法來改變`CreateAt`的值
db.Model(&user).Update("CreatedAt", time.Now())
UpdatedAt
如果模型有UpdatedAt欄位,該欄位的值將會是每次更新記錄的時間,
db.Save(&user) // `UpdatedAt`將會是當前時間
db.Model(&user).Update("name", "jinzhu") // `UpdatedAt`將會是當前時間
DeletedAt
如果模型有DeletedAt欄位,呼叫Delete洗掉該記錄時,將會設定DeletedAt欄位為當前時間,而不是直接將記錄從資料庫中洗掉,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/17370.html
標籤:Go
上一篇:C 實戰練習題目39
