英文:
How to handle with GORM a JSON that corresponds to a database schema?
问题
我正在编写一个后端API,它从数据库中获取一些JSON数据(由GORM处理),然后将数据发送到前端。前端对字段内容进行了一些修改后,也将数据以JSON格式发送回给我。
以下是代码的模拟示例:
package main
import (
"encoding/json"
"fmt"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type User struct {
ID uint
Name string
Card Card
CardID uint
}
type Card struct {
ID uint
Number string
}
func main() {
// 初始化数据库
db, _ := gorm.Open(sqlite.Open("mytest.sqlite"), &gorm.Config{})
db.Debug()
db.AutoMigrate(&User{}, &Card{})
// 创建两张卡片
db.Create(&Card{
Number: "42",
})
db.Create(&Card{
Number: "100",
})
// 查找其中一张卡片
var myCard Card
db.Where(map[string]interface{}{"number": "42"}).First(&myCard)
// 使用该卡片创建一个用户
db.Create(&User{
Name: "john",
Card: myCard,
})
// 查找该用户
var myUser User
db.Preload("Card").Where(map[string]interface{}{"name": "john"}).Last(&myUser)
// 然后将其转换为JSON,并发送到前端。
// 在前端进行了一些更改后,我会收到JSON数据
// 下面是模拟的示例:
// 卡片本身发生了变化
myUser.Card.ID = "2"
myUser.Card.ID = "100"
// 用户名发生了变化
myUser.Name = "mary"
output, _ := json.Marshal(myUser)
fmt.Print(string(output))
// 现在output中保存着JSON字符串
}
// 输出结果
// {"ID":12,"Name":"mary","Card":{"ID":2,"Number":"100"},"CardID":1}
我的问题是如何处理output
,以便将其写回数据库。
我不太了解GORM(或ORM),也不明白如何处理以下情况:
- 卡片的
ID
已更改 - 用户的
Name
已更改
特别是,我不明白GORM是否会自动识别附加的卡片已更改(并且对应于数据库中的一张卡片)。我相信Name
更改不是问题(因为ID
是相同的)。
英文:
I am writing a backend API that sends to the frontend some JSON data from a database (handled by GORM). The frontend, after some modifications to the content of the fields, sends me back the data also as JSON.
Below is a mock-up of the code
package main
import (
"encoding/json"
"fmt"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type User struct {
ID uint
Name string
Card Card
CardID uint
}
type Card struct {
ID uint
Number string
}
func main() {
// initialize the database
db, _ := gorm.Open(sqlite.Open("mytest.sqlite"), &gorm.Config{})
db.Debug()
db.AutoMigrate(&User{}, &Card{})
// create two cards
db.Create(&Card{
Number: "42",
})
db.Create(&Card{
Number: "100",
})
// find one of them
var myCard Card
db.Where(map[string]interface{}{"number": "42"}).First(&myCard)
// create a user with that card
db.Create(&User{
Name: "john",
Card: myCard,
})
// find that user
var myUser User
db.Preload("Card").Where(map[string]interface{}{"name": "john"}).Last(&myUser)
// this is then marshalled to JSON, and sent to a frontend.
// on that frontend there are some changes and I get back the JSON
// this is simulated below:
// the card itself changed
myUser.Card.ID = "2"
myUser.Card.ID = "100"
// the name of the user changed
myUser.Name = "mary"
output, _ := json.Marshal(myUser)
fmt.Print(string(output))
// Now output holds the JSON string
}
// output
// {"ID":12,"Name":"mary","Card":{"ID":2,"Number":"100"},"CardID":1}
My question is about how to handle output
so that it can be written back into the database.
I do not really know GORM (or ORM for that matter) and I do not understand how to handle the fact that:
- the
ID
of thecard
was changed - the
Name
of the user changed
In particular, I do not understand whether GORM will just "know" that the attached card is now different (and corresponds to a card in the database). I believe that the fact that Name
changed is not a problem (because the ID
is the same)
答案1
得分: 2
你可以将JSON主体解码为用户结构,然后使用它进行更新。
func patchUser(w http.ResponseWriter, r *http.Request) {
// 从URL中获取id,例如/users/1
// 你需要使用一个框架或自己实现这个功能
id := getId(r.URL)
// 将主体解码为新用户
patch := User{}
json.NewDecoder(r.Body).Decode(&patch)
// 在给定的id处更新用户
db.Model(User{}).Where("id = ?", id).Updates(patch)
}
你可以在这里找到有关更新的文档:https://gorm.io/docs/update.html
英文:
You can decode the JSON body into a user struct, and then do an update with it.
func patchUser(w http.ResponseWriter, r *http.Request) {
// get the id from the url i.e. /users/1
// you need to use a framework or implement this yourself
id := getId(r.URL)
// decode the body into a new user
patch := User{}
json.NewDecoder(r.Body).Decode(&patch)
// patch the user at the given id
db.Model(User{}).Where("id = ?", id).Updates(patch)
}
You can find docs about updates here: https://gorm.io/docs/update.html
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论