Go语言框架之GORM使用(二) | 青训营

140 阅读4分钟

GORM的使用入门

字段标签

GORM提供了gorm标签来控制字段的类型和权限。

  • type 定义列数据类型,例如bool,int,time等
  • size 定义列的大小,单位为bit
  • colum 自定义列的名,否则默认为struct中的属性名
  • primaryKey 将列定义为主键
  • unique 将列定义为唯一键
  • default 定义列的默认值
  • not null 不可为空
  • comment 注释
  • pricision 定义列的精度
  • autoIncrement 自动增长
  • index 根据参数创建索引,多个字段使用相同的名称则创建复合索引
  • uniqueIndex 创建唯一索引
  • check 创建约束
  • <- 设置写入权限
  • -> 设置读取权限
  • - 忽略该字段
  • embedded 嵌套字段
  • embeddedPrefix 嵌套字段前缀

多个字段标签之间使用;进行分割,例如

type FavoriteSQL struct {  
gorm.Model  
UserID uint `gorm:"type:int;not nul;index:idx_user_id" json:"user_id"`  
VideoID uint `gorm:"type:int;not null;index:idx_video_id" json:"video_id" `  
}

单表增删改查

表结构
type User struct {
  Name   string 
  Age    int    
  Address  *string 
}
创建记录
address = "where"
user := User{Name: "xxx", Age: 18, Address: &address}
result := db.Create(&user) // 通过数据的指针来创建

之所以在Address字段使用指针类型,是为了更好的存nil类型。并且在调用Create方法时,要记得传递的是一个指针。调用完毕后,数据库中返回的值自动就存在了user对象当中,可以直接取出。

同时,如果嫌效率太慢,Create方法也可以进行批量插入,只需要定义var users []User,创造一个切片,并且传递给Create方法,gorm自动会按切片中的数据进行创建。

使用 CreateInBatches 创建时,你还可以指定创建的数量。

查询记录

GORM 提供了 FirstTakeLast 方法,以便从数据库中检索单个对象。

  • First 按主键升序获取第一条记录
  • Take 随机获取一条记录
  • Last 按主键降序获取第一条记录
根据主键查询

DB.Take(&user, 1)

Take的第二个参数,默认会根据主键查询,可以是字符串,可以是数字。

根据条件查询

也可以根据其他条件进行查询,例如DB.Take(&user, "name = ?", "xxx"),使用?当作占位符,将查询的内容放进?当中。等价于SQL语法

SELECT * FROM `user` WHERE name = 'xxx' LIMIT 1

采用这种方式查询不仅方便,还能够有效的防止SQL注入,gorm自动会将参数全部自动转义。

根据结构体查询
var user User
user.Name = "xxx"
DB.Take(&user)

这样就会查询到名字叫做xxx的记录了。

查询多条记录

如果需要查询多条记录,我们可以使用Find方法。

var userList []User
DB.Find(&userList)

和查询一条记录时一样,我们也可以在Find方法中添加参数做到根据主键查询或者依照其他条件查询。

DB.Find(&userList, "name in ?", []string{"xxx", "yyy"})

除了在Find中添加参数以外,我们也可以使用gorm提供的Where方法进行条件查询。

// 获取第一条匹配的记录
db.Where("name = ?", "xxx").First(&user)

gorm也可以使用Or,Not,分组进行查询。

更新记录

查询到记录之后,我们可以通过对结构体进行修改,再调用SaveUpdate方法进行字段的更新。Save会保存所有的字段,即使字段是零值。

var user User
DB.Take(&user)
User.Age = 0
DB.Save(&student)
// UPDATE `students` SET `name`='xx',`age`=0, address`='xxx' WHERE `id` = 1

也可以使用select选择要更新的字段。

如果想要单列批量更新,我们可以使用Update

var userList []User
DB.Find(&userList, "age = ?", 12).Update("address", "xxx")

如果需要更新多列,就需要用到UpdatesUpdates 方法支持 struct 和 map[string]interface{} 参数。它默认不会更新零值。如果想让他更新零值,需要加上Select。 如果需要忽略指定字段,可以使用Omit

删除记录

删除记录可以使用Delete方法,例如依照结构体删除

// user 的 Age 是 10
db.Delete(&student)
// DELETE from students where age = 10;

如果在没有任何条件的情况下执行批量删除,GORM会拒绝执行操作,并返回错误。因此,如果真的需要批量删除,可以使用原生SQL,或者启用AllowGlobalUpdate模式(通过gorm.Session进行设置)

另外,gorm还具有软删除的能力,只要你的结构体包含了gorm.deletedat字段(gorm.Model 已经包含了该字段)。拥有软删除能力的模型调用 Delete 时,记录不会被从数据库中真正删除。但 GORM 会将 DeletedAt 置为当前时间, 并且你不能再通过正常的查询方法找到该记录。可以使用 Unscoped 找到被软删除的记录或者进行永久删除。