承接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找所有数据,注意一个定义单个变量,一个定义列表