gorm(一)


前言

之前已经弄好了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 nullsize, 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根据参数创建索引,多个字段使用相同的名称则创建复合索引,查看 索引 获取详情
uniqueIndexindex 相同,但创建的是唯一索引
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弄的差不多才写了,实际使用一下,踩一点坑,博客才能写的精炼一点。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值