gorm系列-model
程序员文章站
2024-01-03 20:15:34
[TOC] Gorm Model 在使用ORM工具时,通常我们需要在代码中定义模型(Models)与数据库中的数据表进行映射,在GORM中模型(Models)通常是正常定义的结构体、基本的go类型或它们的指针。同时也支持sql.Scanner(扫描)及driver.Valuer(驱动)接口(inte ......
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字段为当前时间,而不是直接将记录从数据库中删除。
推荐阅读
-
ES6入门系列 ----- Reflect
-
MarTech观察系列之六 | 内容是增长的新引擎
-
asp.net core系列 65 正反案例介绍SOLID原则
-
9.2 翻译系列:数据注解特性之---Column【EF 6 Code First系列】
-
8.翻译系列: EF 6中配置领域类(EF 6 Code-First 系列)
-
asp.net core系列 52 Identity 其它关注点
-
[Feature phone 系列]字符信息的显示和绘制原理
-
跟我学: 使用 fireasy 搭建 asp.net core 项目系列之一 —— 开篇
-
【5G系列】如何学习测试协议(2)——NAS选网测试协议6.1.1.1
-
mvc - php中的Model到底扮演什么角色