gorm是一個使用Go語言編寫的ORM框架。文檔齊全,對開發者友好,支持主流數據庫。
gorm介紹
中文官方網站內含十分齊全的中文文檔,有了它你甚至不需要再繼續向下閱讀本文。
安裝
go get -u github.com/jinzhu/gorm
連接數據庫
連接不同的數據庫都需要導入對應數據的驅動程序,GORM
已經貼心的為我們包裝了一些驅動程序,只需要按如下方式導入需要的數據庫驅動即可:
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/mysql"
連接MySQL
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
func main() {
db, err := gorm.Open("mysql", "user:password@(localhost)/dbname?charset=utf8mb4&parseTime=True&loc=Local")
defer db.Close()
}
連接PostgreSQL
基本代碼同上,注意引入對應postgres
驅動並正確指定gorm.Open()
參數。
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
)
func main() {
db, err := gorm.Open("postgres", "host=myhost port=myport user=gorm dbname=gorm password=mypassword")
defer db.Close()
}
連接Sqlite3
基本代碼同上,注意引入對應sqlite
驅動並正確指定gorm.Open()
參數。
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite"
)
func main() {
db, err := gorm.Open("sqlite3", "/tmp/gorm.db")
defer db.Close()
}
連接SQL Server
基本代碼同上,注意引入對應mysql
驅動並正確指定gorm.Open()
參數。
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
func main() {
db, err := gorm.Open("mysql", "sqlserver://username:password@localhost:1433?database=dbname")
defer db.Close()
}
GORM基本示例
創建數據庫
在使用GORM前手動創建數據庫db1
:
CREATE DATABASE db1;
GORM操作MySQL
使用GORM連接上面的db1
進行創建、查詢、更新、刪除操作。
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
// UserInfo 用戶信息
type UserInfo struct {
ID uint
Name string
Gender string
Hobby string
}
func main() {
db, err := gorm.Open("mysql", "root:root1234@(127.0.0.1:13306)/db1?charset=utf8mb4&parseTime=True&loc=Local")
if err!= nil{
panic(err)
}
defer db.Close()
// 自動遷移
db.AutoMigrate(&UserInfo{})
u1 := UserInfo{1, "無情", "男", "籃球"}
u2 := UserInfo{2, "老王", "女", "足球"}
// 創建記錄
db.Create(&u1)
db.Create(&u2)
// 查詢
var u = new(UserInfo)
db.First(u)
fmt.Printf("%#v\n", u)
var uu UserInfo
db.Find(&uu, "hobby=?", "足球")
fmt.Printf("%#v\n", uu)
// 更新
db.Model(&u).Update("hobby", "雙色球")
// 刪除
db.Delete(&u)
}
GORM Model定義
在使用ORM工具時,通常需要在代碼中定義模型(Models)與數據庫中的數據表進行映射,在GORM中模型(Models)通常是正常定義的結構體、基本的go類型或它們的指針。 同時也支持sql.Scanner
及driver.Valuer
接口(interfaces)。
gorm.Model
為了方便模型定義,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
Name string
}
模型定義示例
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:"-"` // 忽略本字段
}
結構體標記(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 | 是否自動完成預加載的相關操作 |
主鍵、表名、列名的約定
主鍵(Primary Key)
GORM 默認會使用名為ID的字段作為表的主鍵。
type User struct {
ID string // 名為`ID`的字段會默認作為表的主鍵
Name string
}
// 使用`AnimalID`作為主鍵
type Animal struct {
AnimalID int64 `gorm:"primary_key"`
Name string
Age int64
}
表名(Table Name)
表名默認就是結構體名稱的復數,例如:
type User struct {} // 默認表名是 `users`
// 將 User 的表名設置為 `profiles`
func (User) TableName() string {
return "profiles"
}
func (u User) TableName() string {
if u.Role == "admin" {
return "admin_users"
} else {
return "users"
}
}
// 禁用默認表名的復數形式,如果置為 true,則 `User` 的默認表名是 `user`
db.SingularTable(true)
也可以通過Table()
指定表名:
// 使用User結構體創建名為`deleted_users`的表
db.Table("deleted_users").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還支持更改默認表名稱規則:
gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string {
return "prefix_" + defaultTableName;
}
列名(Column Name)
列名由字段名稱進行下划線分割來生成
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`
}
時間戳跟蹤
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
字段為當前時間,而不是直接將記錄從數據庫中刪除。