GORM基础知识——CRUD操作| 青训营

71 阅读4分钟

承接Gin框架基础知识——建表、外键设置| 青训营数据表建立完后就是对它们进行CRUD(增删改查)

创建和删除比较简单,先介绍

我们首先使用AutoMigrate创建以下表:

db.AutoMigrate(&UserInfo{}, &Video{}, &Comment{}, &UserLogin{})

表结构如下:

type UserInfo struct {  
    ID int64 `json:"id" gorm:"omitempty"` // 用户id  
    Name string `json:"name" gorm:"omitempty"` // 用户名  
    FollowCount int64 `json:"follow_count" gorm:"omitempty"` // 关注总数  
    FollowerCount int64 `json:"follower_count" gorm:"omitempty"` // 粉丝总数  
    Avatar string `json:"avatar" gorm:"omitempty,default:'avatar-default.jpg'"` // 用户头像  
    BackgroundImage string `json:"background_image" gorm:"omitempty,default:'background_image-default.jpg'"` //用户个人页顶部大图  
    Signature string `json:"signature" gorm:"omitempty,default:'这个人很懒,什么都没有写'"` //个人简介  
    IsFollow bool `json:"is_follow" gorm:"omitempty"` // true-已关注,false-未关注  
    TotalFavorited int64 `json:"total_favorited" gorm:"omitempty,default:0"` //获赞数量  
    WorkCount int64 `json:"work_count" gorm:"omitempty,default:0"` //作品数量  
    FavoriteCount int64 `json:"favorite_count" gorm:"omitempty,default:0"` //点赞数量  
    User *UserLogin `json:"-"` //用户与账号密码之间的一对一  
    Videos []*Video `json:"-"` //用户与投稿视频的一对多  
    Follows []*UserInfo `json:"-" gorm:"many2many:user_relations;"` //用户之间的多对多  
    FavorVideos []*Video `json:"-" gorm:"many2many:user_favor_videos;"` //用户与点赞视频之间的多对多  
    Comments []*Comment `json:"-"` //用户与评论的一对多  
}  
  
// UserLogin 用户登录表,和UserInfo属于一对一关系  
type UserLogin struct {  
    ID int64 `gorm:"primary_key"`  
    UserInfoID int64  
    Username string `gorm:"primary_key"`  
    Password string `gorm:"size:200;notnull"`  
}  
  
type Video struct {  
    ID int64 `json:"id,omitempty"`  
    UserInfoID int64 `json:"-"`  
    Author UserInfo `json:"author,omitempty" gorm:"-"` //这里应该是作者对视频的一对多的关系,而不是视频对作者,故gorm不能存他,但json需要返回它  
    PlayURL string `json:"play_url,omitempty" gorm:"column:play_url"`  
    CoverURL string `json:"cover_url,omitempty" gorm:"column:cover_url"`  
    FavoriteCount int64 `json:"favorite_count,omitempty"`  
    CommentCount int64 `json:"comment_count,omitempty"`  
    IsFavorite bool `json:"is_favorite,omitempty"`  
    Title string `json:"title,omitempty"`  
    Users []*UserInfo `json:"-" gorm:"many2many:user_favor_videos;"`  
    Comments []*Comment `json:"-"`  
    CreatedAt time.Time `json:"-"`  
    UpdatedAt time.Time `json:"-"`  
}  
  
type Comment struct {  
    ID int64 `json:"id"`  
    UserInfoID int64 `json:"-"` //用于一对多关系的id  
    VideoID int64 `json:"-"` //一对多,视频对评论  
    User UserInfo `json:"user" gorm:"-"`  
    Content string `json:"content"`  
    CreatedAt time.Time `json:"-"`  
    CreateDate string `json:"create_date" gorm:"-"`  
}

创建数据

使用Create创建数据,创建一个赋好初值的结构体实体作为Create的参数,通过数据的指针来创建,会返回一个result,你可以访问它的Error查看错误信息,RowsAffected查看插入记录的条数

user := UserLogin{UserInfoID: 2, Username: "1111", Password: "123456"}  
result := db.Create(&user)  
if result.Error != nil {  
    panic(result.Error)  
}

如果你想批量插入,定义一个结构体数组:

users := []*UserLogin{
    UserLogin{...},
    UserLogin{...},
    ...
}

传入Create即可

你也可以使用select来选择需要设置的字段

db.Select(“UserInfoID”, "Username", "Password").Create(&user)

这就相当于:

INSERT INTO users (UserInfoID,Username,Password) VALUES (2, “1111”, "123456")

你可以使用Omit来选择需要忽略传递的字段值:

db.Omit("Username").Create(&user)

删除数据

删除一条记录时,删除对象需要指定主键,否则会触发 批量删除,例如:

user := UserInfo{ID: 10}  
result := db.Delete(&user)  
if result.Error != nil {  
    panic(result.Error)  
}

这里就删除了主键为10的记录

如果你想带额外的条件可以这样:

db.Where("name = ?", "tereaslle").Delete(&user)  

相当于:DELETE from userinfos where id = 10 AND name = "tereaslle";

你还可以不创建结构体实体,通过引用结构体来实现按主键删除

db.Delete(&User{}, 10)

等价于 DELETE FROM users WHERE id = 10;

批量删除:

db.Delete(&users, []int{1,2,3})

更新数据

更新一般使用Update与Save,Save是直接保存结构体实体:

var userInfo = UserInfo{Name: "1122"}  
db.First(&userInfo)  
userInfo.WorkCount = 0  
db.Save(&userInfo)

上面代码先通过userInfo中的信息,找到name为“1122”的第一个用户,将找到的记录传值到userInfo上,修改userInfo的workcount值后保存整个记录,这样的的做法比较通用,但消耗的资源也比较高。

如果仅修改特定几个字段则需要使用Update:

db.Model(&User{}).Where("active = ?", true).Update("name", "hello")

Model传入结构体即表示操作的表,在where中写入条件,按?顺序在后面附上对应值即可,Update只能更新单个列,上例就是将符合条件的name字段赋值为hello

更新多个列就需要用到Updates,可以传入初始化的结构体,也可以传入map[string]interface

Updates(User{Name: "hello", Age: 18, Active: false})

当然你可以通过select与omit选定或忽略特定字段:

db.Model(&user).Select("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "active": false})

db.Model(&user).Omit("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "active": false})

同样,该函数也会返回result

result := db.Model(User{}).Where("role = ?", "admin").Updates(User{Name: "hello", Age: 18})

查询数据

查询的方法有很多,这里介绍比较常用的就是Where+First/Find

var user User
var users []User
db.Where("name = ?", "jinzhu").First(&user)
db.Where("name = ?", "jinzhu").Find(&users)

Where中填条件,First只取第一条数据,Find找所有数据,注意一个定义单个变量,一个定义列表