我有一个结构映射到mysql表,如下所示,并希望更新在PUT请求有效负载中发送的字段
type Notification struct {
Id int64 `json:"id"`
Type NotificationType
Subject string `json:"confidence"`
Body string `json:"body"`
CreatedDate time.Time `json:"created_dt"`
CreatedBy int64 `json:"created_by"`
ParentNotification int64 `json:"parent_id"`
IsExpired bool `json:"expired"`
}
目前我要求所有字段都包含在有效负载中,即使数据未更改并使用 db.Exec(query)语句使用查询更新所有列。
有什么方法可以让客户只包含有效负载中更改的字段并仅更新这些字段?
{
"body" : "new body"
"subject" : "new subject"
}
我正在使用db side中的以下软件包。
"database/sql"
_ "github.com/go-sql-driver/mysql"
答案 0 :(得分:1)
一种做你想做的事情,就是让客户只发送他们想要改变的数据,就是要有一个额外的" param"每个类型" db表"类型。因此,例如,根据您的Notification
类型,您将拥有NotificationParams
类型,如下所示:
type NotificationParams struct {
Id int64 `json:"id"`
// use pointers so that a field that is not present in the json
// will result in a nil pointer value, which tells you that no
// update is needed for that column, it also allows the client
// to send an empty string if they want to delete the content of
// some column, e.g. Body.
Type *NotificationType
Subject *string `json:"confidence"`
Body *string `json:"body"`
// and other fields that you want to allow the client change
}
然后在你的处理程序或者你可以沿着这些方向做点什么:
params := &NotificationParams{} // unmarshal from json
notif := &Notification{} // read from db using params.Id
// change only those fields that were provided
if params.Type != nil {
notif.Type = *params.Type
}
if params.Subject != nil {
notif.Subject = *params.Subject
}
if params.Body != nil {
notif.Body = *params.Body
}
// do some validation...
// if ok save notif using mysql UPDATE
如果你想避免编写大量的if
语句,你可以编写几个" setter"或者"申请"功能(您更喜欢哪个名称)为您执行此操作,每个类型对应您支持的功能,例如:一个用于string
,一个用于time.Time
等等。
以此功能为例:
// The variadic list of functions can be used to transform (think
// sanitization, normalization, etc.) the value before setting
// it to the dst pointer.
func ApplyStr(dst, src *string, fns ...func(string) string) {
if src != nil {
s := *src
for _, fn := range fns {
s = fn(s)
}
*dst = s
}
}
然后你会使用像this playground example这样的函数。
答案 1 :(得分:0)
以下方法使用GORM库在收到有效负载后保留数据:
package main
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"time"
)
type NotificationType struct {
gorm.Model
}
type Notification struct {
gorm.Model
Id int64 `json:"id"`
Type NotificationType
Subject string `json:"confidence"`
Body string `json:"body"`
CreatedDate time.Time `json:"created_dt"`
CreatedBy int64 `json:"created_by"`
ParentNotification int64 `json:"parent_id"`
IsExpired bool `json:"expired"`
}
func main() {
//your handler code to receive and decode payload from client
//save data to database
db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic("failed to connect database")
}
defer db.Close()
// Migrate the schema
db.AutoMigrate(&Notification{})
// Read
var Notification notification
db.First(¬ification, 1) // find notification with id 1 , the id from your payload
// Update the table from notification object
db.Save(¬ification)
}