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 contrallerimport (    "bookManage/dao/mysql"    "bookManage/model"    "github.com/gin-gonic/gin"    "strconv")// CreateBookHandler 创建新的bookfunc 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的listfunc 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 删除bookfunc 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 contrallerimport (    "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 mysqlimport (    "bookManage/model"    "fmt"    gmysql "gorm.io/driver/mysql"    "gorm.io/gorm")var DB *gorm.DBfunc 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 middlewareimport (    "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 modeltype 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 modeltype 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 modeltype BookUser struct {    UserID int64 `gorm:"primaryKey"`    BookID int64 `gorm:"primaryKey"`}
router api_router.go
  1. 路由相关
package routerimport (   "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 routerimport "github.com/gin-gonic/gin"/*加载其他路由文件中的路由*/// 初始化其他文件中的路由func InitRouter() *gin.Engine {   r := gin.Default()   LoadApiRouter(r)   return r}
main.go
  1. 主函数,入口
package mainimport (    "bookManage/dao/mysql"    "bookManage/router")func main() {    mysql.InitMysql()    r := router.InitRouter()    r.Run(":8000")}