bookManager
项目结构
- contraller目录存放相关业务的处理函数
- dao目录存放数据库相关
- middleware存放中间件
- model存放模型
- router存放路由
- main.go项目入口
├── Readme.md
├── contraller
│ ├── book.go
│ └── user.go
├── dao
│ └── mysql
│ └── mysql.go
├── go.mod
├── go.sum
├── main.go
├── middleware
│ └── auth.go
├── model
│ ├── book.go
│ ├── user.go
│ └── user_m2m_book.go
└── router
├── api_router.go
├── init_router.go
└── test_router.go
contraller
book.go
- 处理book相关操作的函数
package contraller
import (
"bookManage/dao/mysql"
"bookManage/model"
"github.com/gin-gonic/gin"
"strconv"
)
// CreateBookHandler 创建新的book
func CreateBookHandler(c *gin.Context) {
p := new(model.Book)
if err := c.ShouldBind(p); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
mysql.DB.Create(p)
c.JSON(200, gin.H{"msg": "success"})
}
// GetBookListHandler 获取book的list
func GetBookListHandler(c *gin.Context) {
books := []model.Book{}
mysql.DB.Preload("Users").Find(&books)
c.JSON(200, gin.H{"books": books})
}
// GetBookDetailHandler 获取book的详情
func GetBookDetailHandler(c *gin.Context) {
idStr := c.Param("id")
bookId, _ := strconv.ParseInt(idStr, 10, 64)
book := model.Book{Id: bookId}
mysql.DB.Find(&book)
c.JSON(200, gin.H{"books": book})
}
// UpdateBookHandler 更新book信息
func UpdateBookHandler(c *gin.Context) {
p := new(model.Book)
if err := c.ShouldBindJSON(p); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
oldBook := &model.Book{Id: p.Id}
var newBook model.Book
if p.Name != "" {
newBook.Name = p.Name
}
if p.Desc != "" {
newBook.Desc = p.Desc
}
mysql.DB.Model(&oldBook).Updates(newBook)
c.JSON(200, gin.H{"book": newBook})
}
// DeleteBookHandler 删除book
func DeleteBookHandler(c *gin.Context) {
idStr := c.Param("id")
bookId, _ := strconv.ParseInt(idStr, 10, 64)
mysql.DB.Select("Users").Delete(&model.Book{Id: bookId})
c.JSON(200, gin.H{"msg": "success"})
}
user.go
- 处理用户登陆相关的函数
package contraller
import (
"bookManage/dao/mysql"
"bookManage/model"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
// RegisterHandler 注册
func RegisterHandler(c *gin.Context) {
p := new(model.User)
if err := c.ShouldBind(p); err != nil {
c.JSON(400, gin.H{"err": err.Error()})
return
}
mysql.DB.Create(p)
c.JSON(200, gin.H{"msg": p})
}
// LoginHandler 登陆
func LoginHandler(c *gin.Context) {
p := new(model.User)
if err := c.ShouldBind(p); err != nil {
c.JSON(403, gin.H{"err": err.Error()})
}
u := model.User{Username: p.Username, Password: p.Password}
if rows := mysql.DB.Where(&u).First(&u).Row(); rows == nil {
c.JSON(403, gin.H{"msg": "error username or password"})
return
}
token := uuid.New().String()
mysql.DB.Model(u).Update("token", token)
c.JSON(200, gin.H{"token": token})
}
dao
mysql
mysql.go
- mysql连接相关的函数
package mysql
import (
"bookManage/model"
"fmt"
gmysql "gorm.io/driver/mysql"
"gorm.io/gorm"
)
var DB *gorm.DB
func InitMysql() { // 1、连接数据库
dsn := "root:123456@tcp(127.0.0.1:3306)/books?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(gmysql.Open(dsn), &gorm.Config{})
if err != nil {
fmt.Println("初始化mysql连接错误", err)
}
DB = db
if err := DB.AutoMigrate(model.User{}, model.Book{}); err != nil {
fmt.Println("自动创建表结构失败:", err)
}
}
middleware
auth.go
- 认证相关的函数
package middleware
import (
"bookManage/dao/mysql"
"bookManage/model"
"github.com/gin-gonic/gin"
)
func AuthMiddleware() func(c *gin.Context) {
return func(c *gin.Context) {
token := c.Request.Header.Get("token")
var u model.User
if rows := mysql.DB.Where("token = ?", token).First(&u).RowsAffected; rows != 1 {
c.JSON(403, gin.H{"msg": "token 错误"})
c.Abort()
return
}
c.Set("UserId", u.Id)
c.Next()
}
}
model
book.go
- book的模型
package model
type Book struct {
Id int64 `json:"id" gorm:"primaryKey"`
Name string `json:"name" gorm:"not null" binding:"required"`
Desc string `json:"desc"`
User []User `gorm:"many2many:book_users"`
}
func (Book) TableName() string {
return "book"
}
user.go
- user的模型
package model
type User struct {
Id int64 `json:"id" gorm:"primaryKey"`
Username string `json:"username" gorm:"not null" binding:"required"`
Password string `json:"password" gorm:"not null" binding:"required"`
Token string `json:"token"`
}
func (User) TableName() string {
return "user"
}
userm2mbook.go
- user和book的中间表模型
package model
type BookUser struct {
UserID int64 `gorm:"primaryKey"`
BookID int64 `gorm:"primaryKey"`
}
router
api_router.go
- 路由相关
package router
import (
"bookManage/contraller"
"bookManage/middleware"
"github.com/gin-gonic/gin"
)
func LoadApiRouter(r *gin.Engine) {
r.POST("/register", contraller.RegisterHandler)
r.POST("/login", contraller.LoginHandler)
v1 := r.Group("/api/v1")
v1.Use(middleware.AuthMiddleware())
v1.POST("book", contraller.CreateBookHandler)
v1.GET("book", contraller.GetBookListHandler)
v1.GET("book/:id", contraller.GetBookDetailHandler)
v1.PUT("book", contraller.UpdateBookHandler)
v1.DELETE("book/:id", contraller.DeleteBookHandler)
}
init_router
- 初始化路由
package router
import "github.com/gin-gonic/gin"
/*
加载其他路由文件中的路由
*/
// 初始化其他文件中的路由
func InitRouter() *gin.Engine {
r := gin.Default()
LoadApiRouter(r)
return r
}
main.go
- 主函数,入口
package main
import (
"bookManage/dao/mysql"
"bookManage/router"
)
func main() {
mysql.InitMysql()
r := router.InitRouter()
r.Run(":8000")
}