【问题标题】:Generic handling CRUD actions in golang在 golang 中通用处理 CRUD 操作
【发布时间】:2019-01-07 14:01:05
【问题描述】:

我正在尝试创建将处理我的 gorm 模型上的所有基本 CRUD 操作的视图。 目标是将模型传递给视图,让所有的魔法发生。

我找到了有关使用反射的主题,所以我做了,但也读到了这不是“golang 方式”。

我遇到的第一个问题是gorm 总是使用“值”表。所以临时解决方案是强制使用来自CommonView的“用户”表或表名

package controllers

import (
    "encoding/json"
    "fmt"
    "github.com/jinzhu/gorm"
    "net/http"
    "reflect"
)

type CommonView struct {
    db        *gorm.DB
    modelType reflect.Type
    model     interface{}
    tableName string
}

func NewCommonView(db *gorm.DB, model interface{}, tableName string) *CommonView {
    return &CommonView{
        db:        db,
        modelType: reflect.TypeOf(model),
        model:     model,
        tableName: tableName,
    }
}

func (cv *CommonView) HandleList(w http.ResponseWriter, r *http.Request) {
    modelSliceReflect := reflect.SliceOf(cv.modelType)
    models := reflect.MakeSlice(modelSliceReflect, 0, 10)

    fmt.Println(modelSliceReflect)
    fmt.Println(models)

    //modelsDirect := reflect.MakeSlice(reflect.TypeOf(cv.model), 0, 0)
    cv.db.Table("users").Find(&models)

    fmt.Println("From db: ")
    fmt.Println(models)

    modelType := reflect.TypeOf(modelSliceReflect)
    fmt.Println("Type name: " + modelType.String())


    modelsJson, _ := json.Marshal(models)

    fmt.Fprint(w, string(modelsJson))
}

型号: 封装模型

import "golang.org/x/crypto/bcrypt"

type User struct {
    Id        string `json:"id" gorm:"type:uuid;primary_key;default:uuid_generate_v4()"`
    FirstName string `json:"firstName"`
    LastName  string `json:"lastName"`
    Email     string `json:"email" gorm:"unique;not null"`
    Password  string `json:"-"`
}

func (User) TableName() string {
    return "user"
}

Gorm 在 DB 中查找行(从 gorm 日志中知道)。但是 json 不会转储它们 - 猜测它的类型错误并且无法处理。 任何想法如何处理这个问题?

如果您还有其他解决 CRUD 视图问题的方法,我也将不胜感激。

【问题讨论】:

  • 你不应该忽略 Go 中的错误:modelsJson, _ := json.Marshal(modelSliceReflect) - 这里的错误可能会显示编组失败的原因。
  • 忘记了,但没有错误。
  • 你用 gorm 填充 &models,但你编组 modelSliceReflect。这看起来不一致。
  • @thst 哦...可能在经过奇怪的测试后离开了。无论如何,这并没有解决任何问题,但感谢您的指点。 (代码已编辑)
  • 你会尝试在 marshall 上发现错误并打印出来吗?不知道你为什么这么确定,编组没有错误...

标签: go go-gorm


【解决方案1】:

问题源于 json 包处理 reflect.Value 的情况不如预期。你可以在这里找到类似的讨论:https://github.com/golang/go/issues/7846

正如您在下面的代码 sn-p 中看到的,reflect.MakeSlice 返回一个类型 Value,而不是一个切片。

slice_empty_reflect_make := reflect.MakeSlice(
                                    reflect.SliceOf(
                                            reflect.TypeOf(5)),
                                    10, 10)

fmt.Printf("Type of reflect.MakeSlice(): %s\n",
           reflect.TypeOf(slice_empty_reflect_make).Name())

这产生:

Type of reflect.MakeSlice(): Value

当您在 json 编组器中输入 Value 时,它将返回一个对象,而不是一个数组:

Json: {}
Error: <nil>

你需要使用.Interface()回到Value的界面:

jsonBytes, err := json.Marshal(slice_empty_reflect_make.Interface())

这是伪装成How do I serialize a map of type [string]reflect.Value?的副本

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-20
    • 2011-02-08
    • 2014-06-14
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 2016-11-03
    相关资源
    最近更新 更多