优秀的编程知识分享平台

网站首页 > 技术文章 正文

golang练习项目-图书管理系统(golang入门书籍)

nanyue 2024-09-09 04:58:43 技术文章 5 ℃

bookManager

项目结构

  1. contraller目录存放相关业务的处理函数
  2. dao目录存放数据库相关
  3. middleware存放中间件
  4. model存放模型
  5. router存放路由
  6. 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

  1. 处理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

  1. 处理用户登陆相关的函数
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

  1. 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

  1. 认证相关的函数
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

  1. 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

  1. 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

  1. user和book的中间表模型
package model

type BookUser struct {
    UserID int64 `gorm:"primaryKey"`
    BookID int64 `gorm:"primaryKey"`
}

router

api_router.go

  1. 路由相关
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

  1. 初始化路由
package router

import "github.com/gin-gonic/gin"

/*
加载其他路由文件中的路由
*/

// 初始化其他文件中的路由

func InitRouter() *gin.Engine {
   r := gin.Default()
   LoadApiRouter(r)
   return r
}

main.go

  1. 主函数,入口
package main

import (
    "bookManage/dao/mysql"
    "bookManage/router"
)

func main() {
    mysql.InitMysql()
    r := router.InitRouter()
    r.Run(":8000")
}

Tags:

最近发表
标签列表