gin-gorm框架整合

🐌 前提

分别学习完GIN、GORM后,下一步我们学习GIN和GORM的整合。我们接下来将实现http接口对外提供书籍的增删改查功能。

   1、新建go project。

   2、命令行执行go mod init,模块下载执行go mod tidy

   3、新建handler、book目录。

   4、下面我给出我的目录结构。

x:xxxWEB-API
│ go.mod
│ go.sum
│ main.go

├─.IDEA
│     misc.xml
│     modules.xml
│     web-api.iml
│     workspace.xml

├─book
│     entity.go
│     input.go
│     repository.go
│     request.go
│     service.go

└─handler
      book.go

🐉 结构说明

在本例中我们可以看到:

gin-gorm框架整合

  • main.go:程序主函数,是程序的入口。

  • handler:存放各个实体类的controllor。

    • book.go:接收book相关请求和参数,传递请求参数给service层进行逻辑处理,并且接收结果封装返回。

  • book:存放book相关,如:book实体类、dao、请求实体类、返回Vo类、service。

    • entity.go:实体类,对应数据库表。结构属性对应数据库表字段。

    • input.go:封装请求处理结果返回,类似Vo类,这里我们没有再进行封装。

    • repository:类似dao层,封装了程序对book表的原子操作。

    • service:上承handler,下接repository,主要业务处理都在这里。

    • request.go:表单请求绑定实体。类似requestbody。

  • go.mod&go.sum:go mod的配置相关。

🐇 方法梳理

下面以createBook功能为例,梳理请求扭转逻辑。

请求调用:main.go->handler.go-request.go->service.go->repository.go-entity.go

返回:repository.go->service.go->handler.go-input.go->main.go

  • main.go

v1.POST("/createBook", bookHandler.CreateBookHandler)
  • handler:book.go

func (h Handler)CreateBookHandler(c *gin.Context){
    ......
    book, err := h.service.Create(requestBook)
    ......
}
  • service.go

func (service *service) Create(requestBook RequestBook) (Book, error){
   ......
   bookRes, err := service.repository.Create(book)
   ......
}
  • repository.go

func (r *repository) Create(book Book) (Book, error){
    err := r.db.Debug().Create(&book).Error
    return book, err
}

由上述代码我们可以看出代码之间是相互调用一层扣一层。

🐛 show me the code

  • main.go

package main

import (
    "Github.com/gin-gonic/gin"
    "gorm.io/driver/MySQL"
    "gorm.io/gorm"
    "log"
    "web-api/book"
    "web-api/handler"
)

func main(){
   // 数据库连接更换成自己的
    dsn := "user:password@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{
        log.Fatal("Database connect error!")
    }
    // 数据库迁移
    db.AutoMigrate(&book.Book{})

   // Repository向外提供服务
    bookRepository := book.NewRepository(db)
   // Service向外提供服务
    bookService := book.NewService(bookRepository)
   // Handler向外提供服务
    bookHandler := handler.NewHandler(bookService)

    router := gin.Default()
   // 路由组
    v1 := router.Group("/v1")

   // 请求入口
    v1.POST("/createBook", bookHandler.CreateBookHandler)
    router.Run(":8888")
}
  • repository.go

package book

import (
    "gorm.io/gorm"
)

type Repository interface {
    Create(book Book) (Book, error)
}

type repository struct {
    db *gorm.DB
}

func NewRepository(db *gorm.DB) *repository{
    return &repository{db}
}

// 新建书记录
func (r *repository) Create(book Book) (Book, error){
    err := r.db.Debug().Create(&book).Error
    return book, err
}
  • service.go

package book

import "fmt"

type Sercice interface {
    Create(book RequestBook) (Book, error)
}

type service struct {
    repository Repository
}

func NewService(repository Repository) *service{
    return &service{repository}
}

// // 新建书服务
func (service *service) Create(requestBook RequestBook) (Book, error){
    price, _ := requestBook.Price.Int64()
    rate, _ := requestBook.Rating.Int64()
    book := Book{
        Description: requestBook.Description,
        Price: int(price),
        Rating: int(rate),
        Title: requestBook.Title,
}
    bookRes, err := service.repository.Create(book)
    if err != nil {
        fmt.Println("========================")
        fmt.Println("Create Book record error")
            fmt.Println("========================")
    }
    return bookRes, err
}
  • handler:book.go

package handler

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "github.com/go-playground/validator/v10"
    "net/http"
    "web-api/book"
)

func NewHandler(sercice book.Sercice) *Handler{
    return &Handler{sercice}
}

type Handler struct {
    service book.Sercice
}

// 新建书handler
func (h Handler)CreateBookHandler(c *gin.Context){
    var requestBook book.RequestBook
    err := c.ShouldBindJSON(&requestBook)
    if err != nil {
        errMessages := []string{}
        for _, e := range err.(validator.ValidationErrors){
            errMessage := fmt.Sprintf("Error on field %s, condition: %s"e.Field(),e.ActualTag())
            errMessages = append(errMessages, errMessage)
        }

        c.JSON(http.StatusBadRequest, gin.H{
            "errors": errMessages,
        })
        return
    }

    book, err := h.service.Create(requestBook)
    if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "error": err,
        })
        return
    }

    c.JSON(http.StatusOK, gin.H{
        "data": book,
    })
}

整体编码格式是,NewXXX函数(供外部调用)返回封装结构体。XXXXX interface内为接口函数,repository实现了Repository,他们之间的关系我理解为Java中的上转型对象。XXXXX struct实现函数(即方法供外部调用),结构体内为下层对象。

🐳 接口测试

postman接口请求截图:

gin-gorm框架整合

可以看到postman调用请求插入数据成功!到这里gin和gorm整合使用就完成了!


📢📢📢欢迎大家在公众号后台留言交流学习!!!📢📢📢

原文始发于微信公众号(fairy with you):gin-gorm框架整合

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/29662.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!