golang gin框架 结构体如何使用mysql的json类型

golang gin框架 结构体如何使用mysql的json类型

最佳答案

你定义一个切片,然后用json.Unmarshal解析到你这个切片里面不就完事了

1年前 评论
xingkong12138 (作者) 1年前
my38778570 (楼主) 1年前
讨论数量: 29

这个问题有点怪呀,gin是web框架,这个库本身和mysql没有关系呀

1年前 评论
my38778570 (楼主) 1年前

你是想问如何把 mysql 中的json数据存储在 golang的 结构体中吗。

1年前 评论
my38778570 (楼主) 1年前
don178 (作者) 1年前
my38778570 (楼主) 1年前
don178 (作者) 1年前

type Courses struct {

Images             string `gorm:"type:json;default:null;" json:"images" label:"图片"`
gorm.Model

} @d

1年前 评论
don178 1年前
my38778570 (作者) (楼主) 1年前
my38778570 (作者) (楼主) 1年前
don178 1年前
my38778570 (作者) (楼主) 1年前
package main

import (
    "dingjijy-golang/model"
    "dingjijy-golang/routes"
)

func main() {
    // 调用数据库
    model.InitDB()
    // 创建路由
    routes.InitRouter()
}
package routes

import (
    "dingjijy-golang/api/admin"
    "dingjijy-golang/middleware"
    "dingjijy-golang/utils"

    "github.com/gin-gonic/gin"
)

func InitRouter() {
    gin.SetMode(utils.AppMode)
    r := gin.Default()

    // 简单的路由组: v1
    adminRouterGroup := r.Group("api/admin")
    {
        adminRouterGroup.POST("login", admin.Login)
        adminRouterGroup.POST("upload", admin.Upload)
    }

    authAdminRouterGroup := r.Group("api/admin").Use(middleware.JwtToken())
    {
        authAdminRouterGroup.POST("categories/store", admin.StoreCategories)
        authAdminRouterGroup.GET("categories/show/:id", admin.ShowCategories)
        authAdminRouterGroup.GET("categories/index", admin.IndexCategories)
        authAdminRouterGroup.PUT("categories/update/:id", admin.UpdateCategories)
        authAdminRouterGroup.DELETE("categories/delete/:id", admin.DeleteCategories)

        authAdminRouterGroup.POST("courses/store", admin.StoreCourses)
        authAdminRouterGroup.GET("courses/show/:id", admin.ShowCourses)
        authAdminRouterGroup.PUT("courses/update/:id", admin.UpdateCourses)
        authAdminRouterGroup.GET("courses/index", admin.IndexCourses)
        authAdminRouterGroup.DELETE("courses/delete/:id", admin.DeleteCourses)
    }

    r.Run(":8080")
}
package admin

import (
    "dingjijy-golang/model"
    "dingjijy-golang/utils/errmsg"
    "fmt"
    "net/http"
    "strconv"

    "github.com/gin-gonic/gin"
)

// courses.Images = strings.Replace(courses.Images, "'", "\"", -1)
func StoreCourses(c *gin.Context) {

    var courses model.Courses
    c.ShouldBindJSON(&courses)
    code := model.CheckCoursesByName(courses.Name)
################################
重点是这里
##################################
    fmt.Println("Images", courses.Images)
    if code == errmsg.ErrorCoursesNameUsed {
        c.JSON(http.StatusOK, gin.H{
            "status":  code,
            "data":    courses,
            "message": errmsg.GetErrMsg(code),
        })
        return
    }
    code2 := model.StoreCourses(&courses)
    c.JSON(http.StatusOK, gin.H{
        "status":  code2,
        "data":    courses,
        "message": errmsg.GetErrMsg(code2),
    })
}

func ShowCourses(c *gin.Context) {
    id, _ := strconv.Atoi(c.Param("id"))
    data, code := model.ShowCoursesById(id)
    c.JSON(http.StatusOK, gin.H{
        "status":  code,
        "data":    data,
        "message": errmsg.GetErrMsg(code),
    })
}

func UpdateCourses(c *gin.Context) {
    var courses model.Courses
    c.ShouldBindJSON(&courses)
    id, _ := strconv.Atoi(c.Param("id"))
    code := model.CheckCoursesNameById(id, courses.Name)
    if code == errmsg.ErrorCoursesNameUsed {
        c.JSON(http.StatusOK, gin.H{
            "status":  code,
            "data":    courses,
            "message": errmsg.GetErrMsg(code),
        })
        return
    }
    code2 := model.UpdateCourses(id, &courses)
    c.JSON(http.StatusOK, gin.H{
        "status":  code2,
        "data":    courses,
        "message": errmsg.GetErrMsg(code2),
    })
}

func IndexCourses(c *gin.Context) {
    page, _ := strconv.Atoi(c.Query("page"))
    limit, _ := strconv.Atoi(c.Query("limit"))
    name := c.Query("name")
    fmt.Printf("page: %v,limit: %v,name: %v\n", page, limit, name)
    if page == 0 {
        page = -1 // -1 不分页
    }
    if limit == 0 {
        limit = -1 // -1 不分页
    }
    categories, count := model.IndexCourses(name, page, limit)
    code := errmsg.Success
    id, _ := c.Get("id")
    account, _ := c.Get("account")
    fmt.Println(id)
    c.JSON(http.StatusOK, gin.H{
        "status":  code,
        "data":    categories,
        "count":   count,
        "message": errmsg.GetErrMsg(code),
        "id":      id,
        "account": account,
    })
}

func DeleteCourses(c *gin.Context) {
    id, _ := strconv.Atoi(c.Param("id"))
    code := model.DeleteCoursesById(id)
    c.JSON(http.StatusOK, gin.H{
        "status":  code,
        "message": errmsg.GetErrMsg(code),
    })
}
1年前 评论
package model

import (
    "dingjijy-golang/utils/errmsg"
    "fmt"

    "github.com/jinzhu/gorm"
)

type Courses struct {
    ACategoriesId      string `gorm:"type:int(10);default:0;index:a_categories_id_idx" json:"a_categories_id" label:"一级分类"`
    BCategoriesId      string `gorm:"type:int(10);default:0;index:b_categories_id_idx" json:"b_categories_id" label:"上级id"`
    Name               string `gorm:"type:varchar(255);default:0;unique_index:name_uniq" json:"name" label:"课程名称"`
    Price              string `gorm:"type:decimal(8,2);default:0;" json:"price" label:"价格"`
    ShareTotal         string `gorm:"type:decimal(8,2);default:0;" json:"share_total" label:"提成金额"`
    Camp               string `gorm:"type:varchar(120);default: null;" json:"camp" label:"营地"`
    Image              string `gorm:"type:varchar(255);default:null;" json:"image" label:"图片"`
    Images             string `gorm:"type:json;default:null;" json:"images" label:"图片"`
    GraphicDetails     string `gorm:"type:longtext;default:null;" json:"graphic_details" label:"图文详情"`
    Schedule           string `gorm:"type:longtext;default:null;" json:"schedule" label:"日程安排"`
    DangerousDetails   string `gorm:"type:longtext;default:null;" json:"dangerous_details" label:"注意事件"`
    Status             string `gorm:"type:tinyint(3);default:1;" json:"status" label:"默认1上架0保存"`
    IsHot              string `gorm:"type:tinyint(3);default:0;" json:"is_hot" label:"是否热门默认0否1是"`
    IsRecommend        string `gorm:"type:tinyint(3);default:0;" json:"is_recommend" label:"是否详情列表推荐默认0否1是"`
    HotListOrder       string `gorm:"type:int(10);default:0;" json:"hot_list_order" label:"热门排序,从小到大"`
    RecommendListOrder string `gorm:"type:int(10);default:0;" json:"recommend_list_order" label:"推荐排序,从小到大"`
    gorm.Model
}

func CheckCoursesByName(name string) (code int) {
    var courses Courses
    db.Select("id").Where("Name = ?", name).First(&courses)
    if courses.ID > 0 {
        return errmsg.ErrorCoursesNameUsed
    }
    return errmsg.ErrorCoursesNotExist
}

func StoreCourses(courses *Courses) (code int) {
    err := db.Create(&courses).Error
    if err != nil {
        return errmsg.Error
    }
    return errmsg.Success
}

func ShowCoursesById(id int) (courses Courses, codo int) {
    db.Where("id = ?", id).First(&courses)
    return courses, errmsg.Success
}

func CheckCoursesNameById(id int, name string) (code int) {
    var courses Courses
    fmt.Printf("id: %v,name: %v\n", id, name)
    db.Select("id").Where("Name = ?", name).Where("Id <> ?", id).Find(&courses)
    fmt.Println(courses.ID)
    if courses.ID > 0 {
        return errmsg.ErrorCoursesNameUsed
    }
    return errmsg.ErrorCoursesNotExist
}

func UpdateCourses(id int, courses *Courses) (code int) {
    maps := map[string]interface{}{
        "a_categories_id":      courses.ACategoriesId,
        "b_categories_id":      courses.BCategoriesId,
        "name":                 courses.Name,
        "price":                courses.Price,
        "share_total":          courses.ShareTotal,
        "camp":                 courses.Camp,
        "image":                courses.Image,
        "images":               courses.Images,
        "graphic_details":      courses.GraphicDetails,
        "schedule":             courses.Schedule,
        "dangerous_details":    courses.DangerousDetails,
        "status":               courses.Status,
        "is_hot":               courses.IsHot,
        "is_recommend":         courses.IsRecommend,
        "hot_list_order":       courses.HotListOrder,
        "recommend_list_order": courses.RecommendListOrder,
    }
    err := db.Model(&Courses{}).Where("id = ?", id).Update(maps).Error
    if err != nil {
        return errmsg.Error
    }
    return errmsg.Success
}

func IndexCourses(name string, page int, limit int) (courses []Courses, count int) {
    sql := db.Model(&courses)
    if name != "" {
        sql = sql.Where("name like ?", "%"+name+"%")
    }
    err = sql.Count(&count).Limit(limit).Offset((page - 1) * limit).Order("id DESC").Find(&courses).Error
    if err != nil && err != gorm.ErrRecordNotFound {
        return nil, 0
    }
    return courses, count
}

func DeleteCoursesById(id int) (codo int) {
    var courses Courses
    err := db.Where("id = ?", id).Delete(&courses).Error
    if err != nil {
        return errmsg.Error
    }
    return errmsg.Success
}

@1

1年前 评论
func CheckCoursesByName(name string) (code int) {}

你这个函数select之后就返回了一个code?直接返回数据库拿到的数据不就完了?

1年前 评论
my38778570 (楼主) 1年前
don178 (作者) 1年前
my38778570 (楼主) 1年前
don178 (作者) 1年前

干嘛非要存json 做一对多的关联不是更简单吗?

1年前 评论
my38778570 (楼主) 1年前

你定义一个切片,然后用json.Unmarshal解析到你这个切片里面不就完事了

1年前 评论
xingkong12138 (作者) 1年前
my38778570 (楼主) 1年前
DianWang

新定义一个JSON类型,拿到数据自动转出来

package types

import (
    "bytes"
    "database/sql/driver"
    "encoding/json"
    "errors"
    jsoniter "github.com/json-iterator/go"
)

type JSON []byte

func (j JSON) Value() (driver.Value, error) {
    if j.IsNull() {
        return nil, nil
    }
    return string(j), nil
}
func (j *JSON) Scan(value interface{}) error {
    if value == nil {
        *j = nil
        return nil
    }
    err := json.Unmarshal(*j, &value)
    if err != nil {
        return err
    }
    //s, ok := value.([]byte)
    //if !ok {
    //    return errors.New("Invalid Scan Source")
    //}
    //*j = append((*j)[:], s...)
    return nil
}
func (m JSON) MarshalJSON() ([]byte, error) {
    if m == nil {
        return []byte("null"), nil
    }
    return m, nil
}
func (m *JSON) UnmarshalJSON(data []byte) error {
    if m == nil {
        return errors.New("null point exception")
    }
    *m = append((*m)[:], data...)
    return nil
}

func (j JSON) IsNull() bool {
    return len(j) == 0 || string(j) == "null"
}
func (j JSON) Equals(j1 JSON) bool {
    return bytes.Equal([]byte(j), []byte(j1))
}

func StructToJSON(value interface{}) JSON {
    bts, _ := jsoniter.Marshal(value)
    return bts
}
1年前 评论
goStruct

看你代码用的是gorm,实现下Scan和Value这两个方法


type User struct {
    gorm.Model
  Name string `gorm:"comment:'用户名'"`
    Profile Profile `gorm:"type:json;comment:'个人信息'"`
}


type Profile struct {
    Email string `json:"email"`
    PhoneNo string `json:"phoneNo"`
}


func (p Profile) Value() (driver.Value, error) {
    return json.Marshal(p
}


func (p Profile) Scan(input interface{}) error {
    return json.Unmarshal(input.([]byte), p)
}
1年前 评论
my38778570 (楼主) 1年前

这个是官方的一个 类型拓展库 。它替我们封装了好了一些常用数据库的类型,比如说 MySQL 的 json 类型和 PostgreSQL 的 json 类型,都可以使用其中的一个叫 JSON 的类型,来完成底层 gorm 到数据的数据处理。我们只需要在业务模型中使用即可。

比如说,直接放在你的这个结构体(模型 model)中定义字段,像这样:

Images    datatypes.JSON     `gorm:"type:json;default:null;" json:"images" label:"图片"`

然后你可以为你的结构体(模型 model)定义一个 GetImages() 的方法,将原来的 datatypes.JSON 解析到你自己想要的一个类型中,比如这样:

// 假如你想要的结构体是这样的
type Image struct {
  ID          int
  Content string
}

// 为你的模型写上获取方法
func (c *Courses) GetImages() []*Image {
    imgs := make([]*Image,0)
    jsonBytes._ := c.Images.MarshalJSON()
    json.Unmarshal(jsonBytes, &imgs)
    return imgs
}
1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!