go17/skills/gin/main.go
2024-11-23 10:55:52 +08:00

144 lines
3.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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"
}