这是我参与「第三届青训营 -后端场」笔记创作活动的的第3篇笔记。
1. 项目搭建
(1)技术栈
后端采用golang框架gin
前端采用vue
数据库使用MySQL,拟定后期加入redis作为缓存数据库
使用gorm操作数据库
gin-jwt进行登录及鉴权操作
(2)初始化项目
下载gin
go get -u github.com/gin-gonic/gin
目录结构
配置文件
2. 数据库设计
(1)MySQL
user表
-- auto-generated definition
create table user
(
id int auto_increment
primary key,
username varchar(50) default '' null comment '账号',
password varchar(255) default '' null comment '密码',
nickname varchar(50) default '' null comment '用户名',
avatar varchar(255) default '' null comment '头像地址',
status int default 1 not null comment '权限状态',
major varchar(50) default '' null comment '专业',
class varchar(50) default '' null comment '班级',
create_at datetime default CURRENT_TIMESTAMP null comment '创建时间',
update_at datetime default CURRENT_TIMESTAMP null comment '修改时间',
constraint user_username_uindex
unique (username)
);
(2)models
Model
package models
import "time"
// Model 定义基础模型类,实现复用
type Model struct {
ID uint `gorm:"primaryKey" json:"id"` // id
CreateAt time.Time `json:"createAt"` // 创建时间
UpdateAt time.Time `json:"updateAt"` // 更新时间
}
User
package models
// Login jwt登录使用
type Login struct {
Username string `form:"username" json:"username" binding:"required"`
Password string `form:"password" json:"password" binding:"required"`
}
type User struct {
Model
Username string `json:"username"` // 账号
Password string `json:"password"` // 密码
Nickname string `json:"nickname"` // 昵称
Avatar string `json:"avatar"` // 头像
Status int `json:"status"` // 权限状态
Major string `json:"major"` // 专业
Class string `json:"class"` // 班级
}
// TableName 设置User的表名为user
func (User) TableName() string {
return "user"
}
func (u User) ToMap() map[string]interface{} {
return map[string]interface{}{
"id": u.ID,
"username": u.Username,
"nickname": u.Nickname,
"avatar": u.Avatar,
"status": u.Status,
"major": u.Major,
"class": u.Class,
"createAt": u.CreateAt,
"updateAt": u.UpdateAt,
}
}
3. dao数据库操作
go get gorm.io/driver/mysql // 安装mysql驱动
go get gorm.io/gorm
(1)初始化,连接数据库
package dao
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"k8s_deploy_gin/pkg/setting"
"log"
)
var db *gorm.DB
func init() {
var (
err error
dbName, user, password, host string
)
sec, err := setting.Cfg.GetSection("database")
if err != nil {
log.Fatal(2, "Fail to get section 'database': %v", err)
}
dbName = sec.Key("NAME").String()
user = sec.Key("USER").String()
password = sec.Key("PASSWORD").String()
host = sec.Key("HOST").String()
dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local",
user, password, host, dbName)
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Println(err)
}
sqlDb, err := db.DB()
if err != nil {
log.Fatal(err)
}
sqlDb.SetMaxIdleConns(10)
sqlDb.SetMaxOpenConns(100)
//defer func() {
// sqlDb.Close()
//}()
}
(2) 通过gorm操作user
package dao
import (
"golang.org/x/crypto/bcrypt"
"k8s_deploy_gin/models"
"time"
)
var users []models.User
// GetUserList 分页返回用户列表(page第几页,pageSize每页几条数据)
func GetUserList(page int, pageSize int) (int, []interface{}) {
// 分页用户列表数据
userList := make([]interface{}, 0, len(users))
// 计算偏移量 Offset指定开始返回记录前要跳过的记录数。
offset := (page - 1) * pageSize
// 查看所有的user,并获取user总数
var total int64
result := db.Order("status DESC").Offset(offset).Limit(pageSize).Where("status > ?", "0").Find(&users).Count(&total)
// 如果返回的数据为0条
if result.RowsAffected == 0 {
return 0, userList
}
// 返回的user总数,用count更好
//total := count
// 查询数据
result.Offset(offset).Limit(pageSize).Find(&users)
for _, userSingle := range users {
userItemMap := userSingle.ToMap()
userList = append(userList, userItemMap)
}
return int(total), userList
}
// GetUserById 通过id获取user
func GetUserById(id int) *models.User {
user := models.User{}
db.First(&user, id)
return &user
}
// GetUserByName 通过name获取user
func GetUserByName(name string) *models.User {
user := models.User{}
result := db.Where("username = ?", name).First(&user)
if result.RowsAffected == 0 {
return nil
}
return &user
}
// CreateUser 新增user
func CreateUser(data map[string]interface{}) bool {
result := db.Create(&models.User{
Model: models.Model{
CreateAt: time.Now(),
UpdateAt: time.Now(),
},
Username: data["username"].(string),
Password: data["password"].(string),
Nickname: data["nickname"].(string),
Status: 1,
})
if result.RowsAffected == 0 {
return false
}
return true
}
// UpdateUser 更新user
func UpdateUser(u *models.User) bool {
u.UpdateAt = time.Now()
result := db.Save(&u)
if result.RowsAffected == 0 {
return false
}
return true
}
// CheckUser 检查密码是否正确
func CheckUser(username string, password string) bool {
user := GetUserByName(username)
if user == nil {
return false
}
err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
if err != nil {
return false
}
return true
}