gin + gorm 实现单模型的curd的父类控制器

Golang
355
0
0
2022-07-05

废话不会说,上代码

父类控制器 base/base.go

type Base struct {
    data  interface{}
}

func (b *Base) SetModel(data interface{}) {
    b.data = data
}

func (b *Base) Create(c *gin.Context) {
    b.setFields(c)
    gorm.DB.Create(b.data)
    c.JSON(200, b.data)
}

func (b *Base) Update(c *gin.Context) {
    b.info(c)
    b.setFields(c)
    gorm.DB.Save(b.data)
    c.JSON(200, b.data)
}

func (b *Base) Info(c *gin.Context) {
    b.info(c)
    c.JSON(200, b.data)
}

func (b *Base) Delete(c *gin.Context) {
    b.info(c)
    gorm.DB.Delete(b.data)
    c.JSON(200, "deleted")
}

func (b *Base) info(c *gin.Context) {
    id := c.Param("id")
    gorm.DB.First(b.data, id)
}

func (b *Base) setFields(c *gin.Context) {
    getType := reflect.TypeOf(b.data).Elem()
    getVal := reflect.ValueOf(b.data).Elem()
    for i := 0; i < getType.NumField(); i++ {
        if getType.Field(i).Tag.Get("action") != "" {
            v := c.DefaultPostForm(getType.Field(i).Tag.Get("json"), "")
            if v == "" {
                continue
            }
            switch getType.Field(i).Type.String() {
            case "uint64":
                if val, err := strconv.Atoi(v); err == nil {
                    getVal.Field(i).SetUint(uint64(val))
                } else {
                    panic(fmt.Sprintf("参数类型错误:%v", err))
                }
            case "string":
                getVal.Field(i).SetString(v)
            }
        }
    }
}
gorm.DB 为gorm连接MySQL实例

子类控制器 controller/user.go

// User 定义控制器 操作模型
type User struct {
    Id       uint64 `json:"id"`
    Email    string `json:"email" action:"1"`
    Password string `json:"password" action:"1"`
}

// UserController 定义控制器 结构体
type UserController struct {
    base.Base
}

// NewUser 实例化控制器
func NewUser() *UserController {
    c := &UserController{}
    c.SetModel(&User{})
    return c
}

子类控制器 controller/bolg.go

// Blog 定义控制器 操作模型
type Blog struct {
    Id     uint64 `json:"id"`
    UserId uint64 `json:"user_id" action:"1"`
    Title  string `json:"title" action:"1"`
}

// BlogController 定义控制器 结构体
type BlogController struct {
    base.Base
}

// NewBlog 实例化控制器
func NewBlog() *BlogController {
    c := &BlogController{}
    c.SetModel(&Blog{})
    return c
}
可以看到上面2个子类控制器基本一样,只需定义好该控制器需要操作的数据模型结构体就行了。

gin 路由设置

    app := gin.Default()
    // user curd
    app.PUT("user/create", func(c *gin.Context) {
        controller.NewUser().Create(c)
    })
    app.GET("user/info/:id", func(c *gin.Context) {
        controller.NewUser().Info(c)
    })
    app.POST("user/update/:id", func(c *gin.Context) {
        controller.NewUser().Update(c)
    })
    app.DELETE("user/delete/:id", func(c *gin.Context) {
        controller.NewUser().Delete(c)
    })
    // blog curd
    app.PUT("blog/create", func(c *gin.Context) {
        controller.NewBlog().Create(c)
    })
    app.GET("blog/info/:id", func(c *gin.Context) {
        controller.NewBlog().Info(c)
    })
    app.POST("blog/update/:id", func(c *gin.Context) {
        controller.NewBlog().Update(c)
    })
    app.DELETE("blog/delete/:id", func(c *gin.Context) {
        controller.NewBlog().Delete(c)
    })
以上基本完成了简单的示例,实际使用中逻辑会复杂写,可以配合struct的tag配合父类setFields函数实现复杂的逻辑。如字段验证validate等。