官方文档
目录
- 3.模型
- 4 约定
- 5 增删改查
- 5.2.3 Not
- 5.2.4 Or
- 5.2.5 内联条件
- 5.2.6 额外查询操作
- 5.2.7 FirstOrInit
- 5.2.8 高级查询
- 5.3 更新
- 5.3.1 更新所有字段
- 5.3.2 更新改变的字段
- 5.3.3 更新选择的字段
- 5.3.4 不用Hooks更新列
- 5.3.5 批量更新
- 5.3.6 使用SQL表达式更新
- 5.3.7 在Hooks中修改值
- 5.3.8 额外更新操作
- 5.4 删除
- 5.4.1 删除记录
- 5.4.2 批量删除
- 5.4.3 软删除
- 6 关联
-
- 6.1 属于
- 6.1.1 属于
- 6.1.2 外键
- 6.1.3 关联外键
- 6.1.4 使用从属
- 6.2 含有一个
- 6.2.1 含有一个
- 6.2.2 外键
- 6.2.3 关联外键
- 6.2.4 多形态关联
- 6.2.5 使用包含一个
- 6.3 含有多个
- 6.3.1 含有多个
- 6.3.2 外键
- 6.3.3 关联外键
- 6.3.4 多形态关联
- 6.3.5 使用包含多个
- 6.4 多对多
- 6.4.1 多对多
- 6.4.2 反向引用
- 6.4.3 外键
- 6.4.4 关联表外键
- 6.4.5 自引用
- 6.4.6 使用多对多
- 6.5 关联
- 6.5.1 自动创建/更新
- 6.5.2 跳过自动更新
- 6.5.3 跳过自动创建
- 6.5.4 跳过自动创建/更新
- 6.5.5 跳过保存引用
- 6.5.6 关联模式
- 6.6 预加载
- 6.6.1 预加载
- 6.6.2 自动预加载
- 6.6.3 嵌套预加载
- 6.6.4 自定义预加载SQL
- 7 教程
- 7.3.3 事务
- 7.3.4 数据迁移
- 7.3.5 原生SQL和SQL生成器
- 7.3.6 通用数据库接口
- 8 高级主题
- 8.1 复合主键
- 8.2 创建插件
- 8.3 GORM Dialects
- 8.4 Logger
-
安装gorm
go get -u github.com/jinzhu/gorm
快速开始
package main import ( "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/sqlite" ) type Product struct { gorm.Model Code string Price uint } func main() { db, err := gorm.Open("sqlite3", "test.db") if err != nil { panic("连接数据库失败") } defer db.Close() // 自动迁移模式 db.AutoMigrate(&Product{}) // 创建 db.Create(&Product{ Code: "L1212", Price: 1000}) // 读取 var product Product db.First(&product, 1) // 查询id为1的product db.First(&product, "code = ?", "L1212") // 查询code为l1212的product // 更新 - 更新product的price为2000 db.Model(&product).Update("Price", 2000) // 删除 - 删除product db.Delete(&product) }
连接数据库
MySQL
import ( "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) func main() { db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local") defer db.Close() }
PostgreSQL
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
import ( "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/sqlite" ) func main() { db, err := gorm.Open("sqlite3", "/tmp/gorm.db") defer db.Close() }
不支持的数据库
GORM正式支持上述的数据库,如果您使用的是不受支持的数据库请按照下面的连接编写对应数据库支持文件。 https://github.com/jinzhu/gorm/blob/master/dialect.go
模型
模型定义
Example
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"` // set field size to 255 MemberNumber *string `gorm:"unique;not null"` // set member number to unique and not null Num int `gorm:"AUTO_INCREMENT"` // set num to auto incrementable Address string `gorm:"index:addr"` // create index with name `addr` for address IgnoreMe int `gorm:"-"` // ignore this field }
结构标签
在声明模型的时候标签是可选的。GORM提供以下标签:
提供的结构标签
标签 描述 Column 指定列名 Type 指定列数据类型 Size 指定列大小,默认255 PRIMARY_KEY 指定列作为主键 UNIQUE 指定列作为唯一索引 DEFAULT 指定列默认值 PRECISION 指定列精度 NOT NULL 指定列NOT NULL AUTO_INCREMENT 指定列是否自动递增 INDEX 创建有或没名称的索引,相同名称创建复合索引 UNIQUE_INDEX 和 INDEX
一样,创建唯一索引EMBEDDED 将struct设置为嵌入 EMBEDDED_PREFIX 设置内嵌结构的前缀名 - 忽略这个字段 关联的结构标签
标签 描述 MANY2MANY 指定联接的表名 FOREIGNKEY 指定外键 ASSOCIATION_FOREIGNKEY 指定关联外键 POLYMORPHIC 指定多态类型 POLYMORPHIC_VALUE 指定多态值 JOINTABLE_FOREIGNKEY 指定联接表的外键 ASSOCIATION_JOINTABLE_FOREIGNKEY 指定联接表的联合外键 SAVE_ASSOCIATIONS 是否自动保存关联 ASSOCIATION_AUTOUPDATE 是否自动更新关联 ASSOCIATION_AUTOCREATE 是否自动创建关联 ASSOCIATION_SAVE_REFERENCE 是否自动保存关联引用 PRELOAD 是否自动预加载关联 约定
gorm.Model
结构
gorm.Model
包括一些基本字段ID
,CreatedAt
,UpdatedAt
,DeletedAt
,你可以将它嵌入你的模型,或者只写你想要的字段// gorm.Model definition type Model struct { ID uint `gorm:"primary_key"` CreatedAt time.Time UpdatedAt time.Time DeletedAt *time.Time } // Inject fields `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt` into model `User` type User struct { gorm.Model Name string } // Declaring model w/o gorm.Model type User struct { ID int Name string }
ID
为默认主键ID
为默认主键,也可以用以下方式人为指定主键type User struct { ID string // field named `ID` will be used as primary field by default Name string } // Set field `AnimalID` as primary field type Animal struct { AnimalID int64 `gorm:"primary_key"` Name string Age int64 }
多元化表名
表名是结构体名称的复数形式
type User struct {} // default table name is `users` // Set User's table name to be `profiles` func (User) TableName() string { return "profiles" } func (u User) TableName() string { if u.Role == "admin" { return "admin_users" } else { return "users" } } // Disable table name's pluralization, if set to true, `User`'s table name will be `user` db.SingularTable(true)
指定表名
// Create `deleted_users` table with struct User's definition 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';
修改默认表名
您可以通过定义
DefaultTableNameHandler
对默认表名应用任何规则gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string { return "prefix_" + 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` } // Overriding Column Name 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) // will set `CreatedAt` to current time // To change its value, you could use `Update` db.Model(&user).Update("CreatedAt", time.Now())
UpdatedAt
当模型有
UpdatedAt
字段,当记录更新的时候,它将被设置成当前时间db.Save(&user) // will set `UpdatedAt` to current time db.Model(&user).Update("name", "jinzhu") // will set `UpdatedAt` to current time
DeletedAt
当模型有
DeletedAt
字段,当删除它们的实例的时候,它们不会从数据库中删除,而是设置DeletedAt
字段为当前时间,参考软删除增删改查
创建
创建记录
user := User{ Name: "Jinzhu", Age: 18, Birthday: time.Now()} db.NewRecord(user) // => returns `true` as primary key is blank db.Create(&user) db.NewRecord(user) // => return `false` after `user` created
默认值
可以通过声明default来修改字段默认值,默认值为tag的内容
type Animal struct { ID int64 Name string `gorm:"default:'galeone'"` Age int64 }
插入SQL将排除那些没有值或值为零的字段,将记录插入数据库后,gorm将从数据库加载这些字段的值。
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值,比如
0
,''
,false
或其他的0值不会被保