Dalam PHP, cara mengembalikan entiti bersarang selepas mencipta objek baharu ialah soalan biasa. Apabila kita perlu mencipta objek baharu dalam kelas dan menggunakannya sebagai atribut entiti lain, kita perlu memberi perhatian kepada beberapa teknik dan kaedah. Pertama, kita boleh mencipta objek baharu dalam pembina kelas dan menetapkannya kepada harta. Kami kemudiannya boleh menggunakan kata kunci $ini untuk merujuk objek semasa dan mengakses sifatnya. Selain itu, kita juga boleh menggunakan kaedah statik atau corak kilang untuk mencipta objek baharu dan mengembalikannya kepada pemanggil. Tanpa mengira kaedah, kunci untuk mengembalikan entiti bersarang adalah dengan betul mengendalikan perhubungan antara objek dan memastikan ia berinteraksi dan menghantar data dengan betul antara entiti. Melalui kaedah ini, kami boleh mencipta dan mengembalikan objek entiti bersarang dalam PHP dengan mudah.
Model account
包含嵌套结构 - currency
和 user
Apabila saya mencipta tika baharu account
dalam pangkalan data dan kemudian mengembalikannya dalam respons, entiti bersarang kosong:
type account struct { basemodel name string `gorm:"size:64;not null" json:"name"` balance decimal.decimal `gorm:"type:decimal(16, 2);default:0;not null;" json:"balance"` userid int `gorm:"not null" json:"-"` user user `gorm:"foreignkey:userid" json:"user"` currencyid int `gorm:"not null" json:"-"` currency currency `gorm:"foreignkey:currencyid" json:"currency"` } type createaccountbody struct { name string `json:"name" binding:"required"` balance decimal.decimal `json:"balance"` currencyid int `json:"currency_id" binding:"required"` } func createaccount(ctx *gin.context) { body := createaccountbody{} if err := ctx.bind(&body); err != nil { log.println("error while binding body:", err) ctx.json( http.statusbadrequest, gin.h{"error": "wrong request parameters"}, ) return } account := account { name: body.name, balance: body.balance, currencyid: body.currencyid, userid: 1, } if result := db.db.create(&account); result.error != nil { log.println("unable to create an account:", result.error) } ctx.json(http.statuscreated, gin.h{"data": account}) }
Untuk mengelakkan masalah ini, saya menggunakan pertanyaan berasingan untuk memuat semula pembolehubah akaun:
db.DB.Create(&account) db.DB.Preload("User").Preload("Currency").Find(&account, account.ID) ctx.JSON(http.StatusCreated, gin.H{"data": account})
Adakah ini cara yang paling berkesan dan betul untuk mencapai hasil yang diinginkan?
Saya akan berkongsi dengan anda bagaimana saya biasanya mengendalikan situasi ini. Pertama, izinkan saya berkongsi kod.
main.go
Failpackage main import ( "context" "gogindemo/handlers" "github.com/gin-gonic/gin" "gorm.io/driver/postgres" "gorm.io/gorm" ) var ( db *gorm.db ctx *gin.context ) func init() { dsn := "host=localhost user=postgres password=postgres dbname=postgres port=5432 sslmode=disable" var err error db, err = gorm.open(postgres.open(dsn), &gorm.config{}) if err != nil { panic(err) } db.automigrate(&handlers.currency{}) db.automigrate(&handlers.user{}) db.automigrate(&handlers.account{}) } func adddb() gin.handlerfunc { return func(ctx *gin.context) { ctx.request = ctx.request.withcontext(context.withvalue(ctx.request.context(), "db", db)) ctx.next() } } func main() { db.create(&handlers.user{id: 1, name: "john doe"}) db.create(&handlers.user{id: 2, name: "mary hut"}) db.create(&handlers.currency{id: 1, name: "eur"}) db.create(&handlers.currency{id: 2, name: "usd"}) r := gin.default() r.post("/account", adddb(), handlers.createaccount) r.run() }
Di sini saya baru menambah kod untuk bootstrap objek pangkalan data dan menambah beberapa data tiruan padanya.
handlers/handlers.go
Failpackage handlers import ( "net/http" "github.com/gin-gonic/gin" "github.com/shopspring/decimal" "gorm.io/gorm" ) type User struct { Id int Name string } type Currency struct { Id int Name string } type Account struct { Id int Name string `gorm:"size:64;not null" json:"name"` Balance decimal.Decimal `gorm:"type:decimal(16, 2);default:0;not null;" json:"balance"` UserID int `gorm:"not null" json:"-"` User User `gorm:"foreignKey:UserID" json:"user"` CurrencyID int `gorm:"not null" json:"-"` Currency Currency `gorm:"foreignKey:CurrencyID" json:"currency"` } type CreateAccountBody struct { Name string `json:"name" binding:"required"` Balance decimal.Decimal `json:"balance"` CurrencyID int `json:"currency_id" binding:"required"` } func CreateAccount(c *gin.Context) { db, ok := c.Request.Context().Value("DB").(*gorm.DB) if !ok { c.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error"}) return } var accountReq CreateAccountBody if err := c.BindJSON(&accountReq); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "wrong request body payload"}) return } // create Account & update the "account" variable account := Account{Name: accountReq.Name, Balance: accountReq.Balance, CurrencyID: accountReq.CurrencyID, UserID: 1} db.Create(&account).Preload("Currency").Preload("User").Find(&account, account.Id) c.IndentedJSON(http.StatusCreated, account) }
Dalam fail ini, saya sebenarnya berkomunikasi dengan pangkalan data dengan melakukannya dalam context
中传递的 db
. Sekarang, kembali kepada soalan anda.
Jika hubungan antara user
/currency
//account 和 user
/account
之间的关系是 1:1
类型,那么,您应该依赖 preload
子句。这将在单独的查询中加载相关实体,而不是将其添加到 inner join
ialah jenis 1:1
, maka anda harus bergantung pada klausa pramuat
. Ini akan memuatkan entiti yang berkaitan dalam pertanyaan berasingan dan bukannya menambahkannya pada klausa inner join
.
Sila beritahu saya jika ini menyelesaikan masalah anda, terima kasih!
Atas ialah kandungan terperinci Bagaimana untuk mengembalikan entiti bersarang selepas mencipta objek baharu?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!