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
}

从golang-gin-realworld-example-app项目学写httpapi (二)的更多相关文章

  1. 从golang-gin-realworld-example-app项目学写httpapi (八)

    https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/common/unit_test.go 单元测试 ...

  2. 从golang-gin-realworld-example-app项目学写httpapi (七)

    https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/hello.go main调用 package ...

  3. 从golang-gin-realworld-example-app项目学写httpapi (六)

    https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/users/validators.go 验证器 ...

  4. 从golang-gin-realworld-example-app项目学写httpapi (五)

    https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/users/middlewares.go 中间件 ...

  5. 从golang-gin-realworld-example-app项目学写httpapi (四)

    https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/users/routers.go 路由定义 pa ...

  6. 从golang-gin-realworld-example-app项目学写httpapi (三)

    https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/users/serializers.go 序列化 ...

  7. 从golang-gin-realworld-example-app项目学写httpapi (一)

    https://wangzitian0.github.io/2013/06/29/zero-to-one-1/ https://github.com/gothinkster/golang-gin-re ...

  8. 【饿了么】—— Vue2.0高仿饿了么核心模块&移动端Web App项目爬坑(三)

    前言:接着上一篇项目总结,这一篇是学习过程记录的最后一篇,这里会梳理:评论组件.商家组件.优化.打包.相关资料链接.项目github地址:https://github.com/66Web/ljq_el ...

  9. Golang Gin 项目包依赖管理 godep 使用

    Golang Gin 项目包依赖管理 godep 使用 标签(空格分隔): Go 在按照github.com/tools/godep文档go get完包以后,调整项目结构为$GOPATH/src/$P ...

随机推荐

  1. Javascript框架设计思路图

    这个系列的随笔都是关于Javascript框架设计一书的读书笔记(作者是司徒正美),不是本人原创!!! 一.简介: 1.市面上主流的JS框架,大多数是由一个个模块组合而成,模块化是大多数让软件所遵循的 ...

  2. 西蒙布朗-C4模型

    关于 C4 模型的一些解释 C4 模型是来自 software architecture for developers 一书的定义,指的是 Context 上下文场景.Container 容器.Com ...

  3. JavaScript设计模式-20.责任链模式

    <html> <head> <title>javascript高级语法20-责任链模式</title> </head> <body&g ...

  4. 一头扎进Spring之---------Spring七大核心模块

    Spring七大核心模块 核心容器(Spring Core) 核心容器提供Spring框架的基本功能.Spring以bean的方式组织和管理Java应用中的各个组件及其关系.Spring使用BeanF ...

  5. spring mongodb中去掉_class列

    调用mongoTemplate的save方法时, spring-data-mongodb的TypeConverter会自动给document添加一个_class属性, 值是你保存的类名. 这种设计并没 ...

  6. 微软URLRewriter.dll的url重写的简单使用

    1.先下载MSDNURLRewriting.zip包,打开代码生成URLRewriter.dll文件: 2.将URLRewriter.dll文件引用到项目中: 3.在web.config文件中  &l ...

  7. 解析Excel----ExcelHelper

    public static class ExcelHelper { /// <summary> /// 获取单元格的值 /// </summary> /// <param ...

  8. JAVA泛型——逆变

    在上篇<JAVA泛型——协变>这篇文章中遗留以下问题——协变不能解决将子类型添加到父类型的泛型列表中.本篇将用逆变来解决这个问题. 实验准备 我们首先增加以下方法,见代码清单1所示. 代码 ...

  9. 问题集录--TensorFlow深度学习

    TensorFlow深度学习框架 Google不仅是大数据和云计算的领导者,在机器学习和深度学习上也有很好的实践和积累,在2015年年底开源了内部使用的深度学习框架TensorFlow. 与Caffe ...

  10. 【译】Steve Yegge的文章《Practicing Programming》

    与你所相信的恰恰相反,单纯地每天埋头于工作并不能算是真正意义上的锻炼——参加会议并不能锻炼你的人际交往能力:回复邮件并不能提高你的打字水平.你必须定期留出时间,集中锻炼,这样才能把事情做得更好.我认识 ...