gorm系列-model


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字段為當前時間,而不是直接將記錄從數據庫中刪除。


免責聲明!

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



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