文章目录
前言
之前已经弄好了golang+vscode的开发环境和数据库,gin的文档也过了一遍,gin框架并没有自带的orm,所以一个好用的orm就显得很重要了,特别是我是从django转过来的,一个链式的方便使用的orm会事半功倍,看了一些主流的gin框架开源项目,很多用的都是gorm,所以决定学习一下。一、安装
在配置了go module的项目根目录下执行
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
二、连接数据库和迁移
1.连接数据库
dsn := "root:123456@tcp(127.0.0.1:3306)/ginweb?charset=utf8mb4&parseTime=True&loc=Local"
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
2.迁移
gorm这里的迁移,只会增加之前不存在的索引和字段等等,并不会删除之前存在的字段。比如说修改一个字段的名字,migrate之后,新老的字段都会存在,即新增一个字段,不会删除老的字段。
db.AutoMigrate(&User{}, &Project{})
三、模型
1.模型
type User struct {
gorm.Model
Name string
Email *string
}
gorm.Model结构体包括
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
迁移到数据库之后的表结构如下
默认情况下,GORM 使用 ID 作为主键,使用结构体名的蛇形复数作为表名,字段名的蛇形作为列名,例如model定义的字段名为MemberNumber生成的字段名为member_number,model结构体名为User,生成的表名为users。
2.模型字段标签
标签名 | 作用 |
---|---|
column | 指定 db 列名 |
type | 列数据类型,推荐使用兼容性好的通用类型,例如:所有数据库都支持 bool、int、uint、float、string、time、bytes 并且可以和其他标签一起使用,例如:not null 、size , autoIncrement … 像 varbinary(8) 这样指定数据库数据类型也是支持的。在使用指定数据库数据类型时,它需要是完整的数据库数据类型,如:MEDIUMINT UNSIGNED not NULL AUTO_INSTREMENT |
size | 指定列大小,例如:size:256 |
primaryKey | 指定列为主键 |
unique | 指定列为唯一 |
default | 指定列的默认值 |
precision | 指定列的精度 |
scale | 指定列大小 |
not null | 指定列为 NOT NULL |
autoIncrement | 指定列为自动增长 |
embedded | 嵌套字段 |
embeddedPrefix | 嵌入字段的列名前缀 |
autoCreateTime | 创建时追踪当前时间,对于 int 字段,它会追踪时间戳秒数,您可以使用 nano /milli 来追踪纳秒、毫秒时间戳,例如:autoCreateTime:nano |
autoUpdateTime | 创建/更新时追踪当前时间,对于 int 字段,它会追踪时间戳秒数,您可以使用 nano /milli 来追踪纳秒、毫秒时间戳,例如:autoUpdateTime:milli |
index | 根据参数创建索引,多个字段使用相同的名称则创建复合索引,查看 索引 获取详情 |
uniqueIndex | 与 index 相同,但创建的是唯一索引 |
check | 创建检查约束,例如 check:age > 13 ,查看 约束 获取详情 |
<- | 设置字段写入的权限, <-:create 只创建、<-:update 只更新、<-:false 无写入权限、<- 创建和更新权限 |
-> | 设置字段读的权限,->:false 无读权限 |
- | 忽略该字段,- 无读写权限 |
type User struct {
gorm.Model
Name string `gorm:"size:128;not null"`
Email string `gorm:"size:128;not null;primaryKey"`
MemberNumber int64 `gorm:"size:128;not null"`
}
3.嵌入结构体
可以使用标签 embeddedPrefix 来为 db 中的字段名添加前缀,例如
type User struct {
gorm.Model
Name string
}
// 等效于
type User struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
Name string
}
也可以添加前缀
type Blog struct {
ID int
Author Author `gorm:"embedded;embeddedPrefix:author_"`
Upvotes int32
}
// 等效于
type Blog struct {
ID int64
AuthorName string
AuthorEmail string
Upvotes int32
}
4.关联关系
Belongs To
-
会与另一个模型建立了一对一的连接。 这种模型的每一个实例都“属于”另一个模型的一个实例。
type User struct { gorm.Model Name string Email string GroupID int Group Group } type Group struct { gorm.Model Name string Code string }
-
要定义一个belong to关系,必须存在外键,默认的外键使用拥有者的类型名加上主键名,例如GroupID.
-
也可以通过foreignKey标签自定义外键,或者使用标签references重写引用
type User struct { gorm.Model Name string Email string GroupID int Group Group `gorm:"references:Code"` // 使用 Code 作为引用 }
-
外键约束,可以通过为标签 constraint 配置 OnUpdate、OnDelete 实现外键约束,在使用 GORM 进行迁移时它会被创建
type User struct { gorm.Model Name string Email string GroupID int Group Group `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"` }
Has one
- 与另一个模型建立一对一的关联,但它和一对一关系有些许不同。 这种关联表明一个模型的每个实例都包含或拥有另一个模型的一个实例。
// User 有一张 CreditCard,CreditCardID 是外键 type User struct { gorm.Model CreditCard CreditCard } type CreditCard struct { gorm.Model Number string UserID uint //写法与belongs to稍微不一样 }
- 重写外键重写引用和Belongs to一样通过foreignKey标签和references标签
- 外键约束也和belongs to一样
Has many
- 与另一个模型建立了一对多的连接。 不同于 has one,拥有者可以有零或多个关联模型。
// User 有多张 CreditCard,UserID 是外键 type User struct { gorm.Model CreditCards []CreditCard } type CreditCard struct { gorm.Model Number string UserID uint }
- 重写外键重写引用一样通过foreignKey标签和references标签、
- 外键约束也和has one一样通过constraint标签
- GORM 为 has one 和 has many 提供了多态关联支持,它会将拥有者实体的表名、主键都保存到多态类型的字段中。
type Dog struct { ID int Name string Toys []Toy `gorm:"polymorphic:Owner;"` } type Toy struct { ID int Name string OwnerID int OwnerType string } db.Create(&Dog{Name: "dog1", Toy: []Toy{{Name: "toy1"}, {Name: "toy2"}}}) // INSERT INTO `dogs` (`name`) VALUES ("dog1") // INSERT INTO `toys` (`name`,`owner_id`,`owner_type`) VALUES ("toy1","1","dogs"), ("toy2","1","dogs")
Many to Many
- 多对多关联关系,会在两个models中间添加一张链接表,链接表会自动创建,例如,一个user可以说多种语言,一个语言也会有多个user会说。
// User 拥有并属于多种 language,`user_languages` 是连接表 type User struct { gorm.Model Languages []Language `gorm:"many2many:user_languages;"` } type Language struct { gorm.Model Name string }
- 反向引用
// User 拥有并属于多种 language,`user_languages` 是连接表 type User struct { gorm.Model Languages []*Language `gorm:"many2many:user_languages;"` } type Language struct { gorm.Model Name string Users []*User `gorm:"many2many:user_languages;"` }
总结
未完待续…
本来以为有python orm的使用经验,这个应该上手很快的才对。
过了一遍才感觉学习曲线有点陡峭,估计得慢慢边写边摸索才行。
下一篇grom的博客,应该会在我的gin练手demo弄的差不多才写了,实际使用一下,踩一点坑,博客才能写的精炼一点。