讨论数量:
你是想问如何把 mysql 中的json数据存储在 golang的 结构体中吗。
type Courses struct {
Images string `gorm:"type:json;default:null;" json:"images" label:"图片"`
gorm.Model
} @d
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),
})
}
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
func CheckCoursesByName(name string) (code int) {}
你这个函数select之后就返回了一个code?直接返回数据库拿到的数据不就完了?
新定义一个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
}
看你代码用的是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)
}
这个是官方的一个 类型拓展库 。它替我们封装了好了一些常用数据库的类型,比如说 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
}
你定义一个切片,然后用json.Unmarshal解析到你这个切片里面不就完事了