如何使用GORM处理与数据库模式对应的JSON数据?

huangapple go评论94阅读模式
英文:

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 the card 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

huangapple
  • 本文由 发表于 2022年2月23日 03:41:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/71227369.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定