从golang-gin-realworld-example-app项目学写httpapi (二)
2024-09-20 11:43:06
https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/users/models.go
模型定义
users/models.go
package users
import (
"errors"
"github.com/jinzhu/gorm"
"github.com/wangzitian0/golang-gin-starter-kit/common"
"golang.org/x/crypto/bcrypt"
)
// UserModel对象,对应用户表
// gorm结构体标记,常用的column, type, size, primary_key, unique, index, unique_index, not null, -(忽略此字段)
type UserModel struct {
ID uint `gorm:"primary_key"`
Username string `gorm:"column:username"`
Email string `gorm:"column:email;unique_index"`
Bio string `gorm:"column:bio;size:1024"`
Image *string `gorm:"column:image"`
PasswordHash string `gorm:"column:password;not null"`
}
// FollowModel对象,对应关注表
// gorm.Model 是一个包含了基本字段的结构(struct), 其中包括字段: ID、CreatedAt、UpdatedAt、DeletedAt(逻辑删除字段)
type FollowModel struct {
gorm.Model
Following UserModel
FollowingID uint
FollowedBy UserModel
FollowedByID uint
}
// 函数 用于创建表结构
// 如果不特别指定表名,以对象名大写单词拆分,用下划线连接,未尾加s 指定表名,如UserModel -> user_models
func AutoMigrate() {
// 获取数据库连接
db := common.GetDB()
// 整合表结构,会创建新增的字段,不会改变原有字段内容,可以选择db.CreateTable代替
db.AutoMigrate(&UserModel{})
db.AutoMigrate(&FollowModel{})
//db.CreateTable(&UserModel{})
//db.CreateTable(&FollowModel{})
}
// UserModel对象的内置方法 用于设置密码, 使用 if err := user.setPassword("password0"); err !=nil { ... }
func (u *UserModel) setPassword(password string) error {
if len(password) == 0 {
return errors.New("password should not be empty!")
}
bytePassword := []byte(password)
// `bcrypt generator cost` 取值 [4, 32] 间
passwordHash, _ := bcrypt.GenerateFromPassword(bytePassword, bcrypt.DefaultCost)
u.PasswordHash = string(passwordHash)
return nil
}
// UserModel对象的内置方法 用于校验密码,使用 if err := user.checkPassword("password0"); err != nil { ... }
func (u *UserModel) checkPassword(password string) error {
bytePassword := []byte(password)
byteHashedPassword := []byte(u.PasswordHash)
return bcrypt.CompareHashAndPassword(byteHashedPassword, bytePassword)
}
// UserModel对象相关的函数 用于查找符合条件的第一条记录,使用 user, err := FindOneUser(&UserModel{Username: "username0"})
func FindOneUser(condition interface{}) (UserModel, error) {
db := common.GetDB()
var model UserModel
// condition使用Struct 或者 Map
err := db.Where(condition).First(&model).Error
return model, err
}
// UserModel对象相关的函数 用于插入记录,使用 if err := SaveOne(&userModel); err != nil { ... }
func SaveOne(data interface{}) error {
db := common.GetDB()
err := db.Save(data).Error
//err := db.Create(data).Error
return err
}
// UserModel对象的内置方法 用于更新记录,使用 if err := user.Update(UserModel{Username: "wangzitian0"}); err !=nil { ... }
func (model *UserModel) Update(data interface{}) error {
db := common.GetDB()
err := db.Model(model).Update(data).Error
return err
}
// UserModel对象的内置方法 建立用户间关注(user1 -> user2),使用 if err := user1.following(user2); err != nil { ... }
func (u UserModel) following(v UserModel) error {
db := common.GetDB()
var follow FollowModel
// 查询是否建立关注,如果没有则建立
err := db.FirstOrCreate(&follow, &FollowModel{
FollowingID: v.ID,
FollowedByID: u.ID,
}).Error
return err
}
// UserModel对象的内置方法 查询用户间是否关注(user1 -> user2),使用 if ok := user1.isFollowing(user2); if ok { ... }
func (u UserModel) isFollowing(v UserModel) bool {
db := common.GetDB()
var follow FollowModel
db.Where(FollowModel{
FollowingID: v.ID,
FollowedByID: u.ID,
}).First(&follow)
// 查询是否关注,如果有关注,返回True(用户ID非0值),没有关注(用户ID为0值)
return follow.ID != 0
}
// UserModel对象的内置方法 取消用户间关注,使用 if err := user1.unFollowing(user2); err != nil { ... }
func (u UserModel) unFollowing(v UserModel) error {
db := common.GetDB()
err := db.Where(FollowModel{
FollowingID: v.ID,
FollowedByID: u.ID,
}).Delete(FollowModel{}).Error
//因为FollowModel包含DeletedAt字段,此处为逻辑删除,实际执行的是 UPDATE follow_models SET deleted_at="2013-10-29 10:23" WHERE ...;
return err
}
// UserModel对象的内置方法 查询指定用户的所有关注,使用 followings := user1.GetFollowings()
func (u UserModel) GetFollowings() []UserModel {
db := common.GetDB()
// 事务处理开始
tx := db.Begin()
var follows []FollowModel
var followings []UserModel
// 获取关注表里所有相关的关联记录
tx.Where(FollowModel{
FollowedByID: u.ID,
}).Find(&follows)
// 循环每条关联记录
for _, follow := range follows {
var userModel UserModel
// 第2参数Following为外键名
tx.Model(&follow).Related(&userModel, "Following")
followings = append(followings, userModel)
}
// 事务处理结束
tx.Commit()
return followings
}
最新文章
- 快速上手php:使用PhpStrom调试php
- java:hibernate + oracle之坑爹的clob
- python基础-range用法_python2.x和3.x的区别
- NOI2005 聪聪和可可
- 【spring】 <;tx:annotation-driven />; 的理解 【转载的】
- rsync --exclude 参数
- JavaScript 基础一
- http协议和web本质(转)
- log4j打印出线程号和方法名
- 【.Net Framework 体积大?】不安装.net framework 也能运行!?原理简介-2
- JAVA蓝桥杯黄金分割数,涉及到bigdecimal
- Vue中axios的使用技巧配置项详解
- ht学习流程
- Linux驱动之异步通知的应用
- 【Spark工作原理】stage划分原理理解
- 调用微信JS-SDK配置签名
- jquery 初始化数据 添加html 第一次玩0.0
- 【xsy2913】 enos 动态dp
- BZOJ3473:字符串(后缀数组,主席树,二分,ST表)
- geoserver 源码介绍
热门文章
- html5+js+.Net的即时多人聊天
- Xamarin Mono For Android 4.6.07004看不到新建android
- CentOS 7进入救援模式的方法
- kafka多线程消费topic的问题
- SpringBoot集成WebSocket【基于STOMP协议】进行点对点[一对一]和广播[一对多]实时推送
- JDK源码--ArrayList浅析
- STL 排序(转载)
- 转载:BIO | NIO | AIO
- SQL:存储过程
- [转]在windows service中使用timer