目前正在开发Golang中的API Rest。我有CRUD所有表的过程。现在有人要我开发一个端点,根据URL中发送的参数在其中一个表中进行搜索。假设这是我对该表的结构:
type Media struct {
ID uint
Key string
RecordKey string
RecordID string
SystemMediaKey string
MediaObjectID string
ChangedByID string
ChangedByKey string
MediaCategory string
MimeType string
ShortDescription string
LongDescription string
EntryTimestamp time.Time
ModificationTimestamp time.Time
DeletedAtTimestamp *time.Time
MediaModificationTimestamp time.Time
MediaURL string
MediaHTML string
Order int
Group string
Width int
Height int
ImageSize string
ResourceName string
ClassName string
Permission *string
MediaStatus string
}
现在,他可以在URL中向我发送全部或部分字段,我需要将这些值分配给我的结构,以便能够根据分配给对象的数据在数据库中进行搜索。
我正在使用Gorm处理数据库,gorilla / schema的所有内容,以便在POST请求和Julien Schmidt路由器上分配值。现在,我的问题是:
答案 0 :(得分:1)
您可以使用reflect
包来迭代字段并按名称设置它们。请注意,reflect
软件包使用起来非常困难,如果使用不当,会出现panic
的一些危险。
另请注意,url.Values.Get
仅返回第一个值(有关详细信息,请参阅https://godoc.org/net/url#Values.Get)
编辑:我添加了代码来解释结构中的指针。他们的处理方式不同。
https://play.golang.org/p/AO4lYx7xka
package main
import (
"fmt"
"net/url"
"reflect"
"time"
)
type Media struct {
ID uint
Key string
RecordKey string
RecordID string
SystemMediaKey string
MediaObjectID string
ChangedByID string
ChangedByKey string
MediaCategory string
MimeType string
ShortDescription string
LongDescription string
EntryTimestamp time.Time
ModificationTimestamp time.Time
DeletedAtTimestamp *time.Time
MediaModificationTimestamp time.Time
MediaURL string
MediaHTML string
Order int
Group string
Width int
Height int
ImageSize string
ResourceName string
ClassName string
Permission *string
MediaStatus string
}
func main() {
testUrl := "www.example.com/test?MimeType=themimetype&Key=thekey&Permission=admin"
u, err := url.Parse(testUrl)
if err != nil {
fmt.Println(err)
return
}
params := u.Query()
media := &Media{}
val := reflect.ValueOf(media)
for i := 0; i < val.Elem().NumField(); i++ {
// get the reflect.StructField so we can get the Name
f := val.Elem().Type().Field(i)
// check if URL.Values contains the field
if v := params.Get(f.Name); v != "" {
// get the reflect.Value associated with the Field
field := val.Elem().FieldByName(f.Name)
kind := field.Kind()
// you must switch for each reflect.Kind (associated with the type in your struct)
// so you know which Set... method to call
switch kind {
case reflect.String:
field.SetString(v)
case reflect.Ptr:
// pointers are a special case that must be handled manually unfortunately.
// because they default to nil, calling Elem() won't reveal the underlying type
// so you must simply string match the struct values that are pointers.
switch f.Name {
case "Permission":
newVal := reflect.New(reflect.TypeOf(v))
newVal.Elem().SetString(v)
field.Set(newVal.Elem().Addr())
case "DeletedAtTimestamp":
}
}
}
}
fmt.Printf("%#v\n", media)
fmt.Println(*media.Permission)
}
答案 1 :(得分:0)
我终于设法使用this library将地图转换为结构。唯一的问题是,我必须预先处理URL.Query() Values
返回的地图,因为它为每个值返回一个数组,我只需要值而不是数组。