package main import ( "fmt" "log" "net/http" "github.com/gin-gonic/gin" "gorm.io/driver/mysql" "gorm.io/gorm" ) // 初始化数据库, 能过与数据库交互的 连接池对象: db func setupDatabase() *gorm.DB { dsn := "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { panic("failed to connect database") } db.AutoMigrate(&Book{}) // 自动迁移 return db.Debug() } func Failed(ctx *gin.Context, err error) { ctx.JSON(http.StatusBadRequest, gin.H{"code": 0, "msg": err.Error()}) } // 规定好风格: JSON Restful Api func main() { // gin Engine, 它包装了http server server := gin.Default() db := setupDatabase() // 配置业务路有, Book类型的资源的 一套简单的CRUD // 创建Book -> Book // POST, Body book := server.Group("/api/books") book.POST("", func(ctx *gin.Context) { // 获取Book用户传达的参数 ins := new(Book) if err := ctx.ShouldBindJSON(ins); err != nil { Failed(ctx, err) return } // book, save if err := db.Save(ins).Error; err != nil { Failed(ctx, err) return } ctx.JSON(http.StatusOK, ins) }) // 查询Book列表 -> []*Book // SELECT * FROM `books` book.GET("", func(ctx *gin.Context) { var books []Book if err := db.Find(&books).Error; err != nil { Failed(ctx, err) return } ctx.JSON(http.StatusOK, books) }) // 查询Book详情 book.GET("/:isbn", func(ctx *gin.Context) { var ins Book id := ctx.Param("isbn") if err := db.Where("isbn = ?", id).Take(&ins).Error; err != nil { Failed(ctx, fmt.Errorf("Book not found")) return } ctx.JSON(http.StatusOK, ins) }) // 更新Book book.PUT("/:isbn", func(ctx *gin.Context) { id := ctx.Param("isbn") // 获取用户参数, 读取用户的更新参数 req := BookSpec{} if err := ctx.ShouldBindJSON(&req); err != nil { Failed(ctx, err) return } // gorm更新是,如果字段为零值 就不更新该字段, is_sale 没办法更新为false // 如果越到零值,也需要更新,则需要转化为 指针类型 if err := db.Where("isbn = ?", id).Model(&Book{}).Updates(req).Error; err != nil { Failed(ctx, err) return } // 针对有零值的字段独立更新 // if err := db.Where("isbn = ?", id).Model(&Book{}).Update("is_sale", req.IsSale).Error; err != nil { // Failed(ctx, err) // return // } // // ...... // 再次查询出来 var ins Book if err := db.Where("isbn = ?", id).Take(&ins).Error; err != nil { Failed(ctx, fmt.Errorf("Book not found")) return } // 查询出更新后的数据 ctx.JSON(http.StatusOK, ins) }) // 删除Book book.DELETE("/:isbn", func(ctx *gin.Context) { id := ctx.Param("isbn") if err := db.Where("isbn = ?", id).Delete(&Book{}).Error; err != nil { Failed(ctx, err) return } }) if err := server.Run("127.0.0.1:8080"); err != nil { log.Println(err) } } // Book 结构体定义 type Book struct { // grom:"column:isbn;", 具体文档: https://gorm.io/docs/models.html#Fields-Tags IsBN uint `json:"isbn" gorm:"primaryKey;column:isbn"` BookSpec } type BookSpec struct { Title string `json:"title" gorm:"column:title;type:varchar(200)"` Author string `json:"author" gorm:"column:author;type:varchar(200);index"` Price float64 `json:"price" gorm:"column:price"` // bool false // nil 是零值, false IsSale *bool `json:"is_sale" gorm:"column:is_sale"` } // 定义该对象映射到数据里 表的名称 func (t *Book) TableName() string { return "books" }