使用 gorm 模型的嵌套结构
Nested structs using gorm model
我有一个名为 User 的结构:
type User struct {
Email string
Name string
}
和名为 UserDALModel 的结构:
type UserDALModel struct {
gorm.Model
models.User
}
gorm 模型如下所示:
type Model struct {
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time `sql:"index"`
}
这可以使 UserDALModel 与 gorm 模型和用户模型嵌套,因此输出将是:
{
ID
CreatedAt
UpdatedAt
DeletedAt
Email
Name
}
现在输出是:
{
Model: {
ID
CreatedAt
UpdatedAt
DeletedAt
}
User: {
Name
Email
}
}
根据 gorm 中的 this test,我认为您需要向结构中添加一个 embedded
标记。
type UserDALModel struct {
gorm.Model `gorm:"embedded"`
models.User `gorm:"embedded"`
}
如果需要,您还可以指定前缀 embedded_prefix
。
我找到了答案:
type UserModel struct {
Email string
Name string
}
type UserDALModel struct {
gorm.Model
*UserModal
}
------------------------------
user := UserModel{"name", "email@email.com"}
userDALModel := UserDALModel{}
userDal.UserModal = &user
注意在同一列中嵌入两个结构:
package tests
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"testing"
)
type A struct {
X string
Y string
}
type B struct {
X string
Y string
}
type AB struct {
B B `gorm:"embedded"` // Embedded struct B before struct A
A A `gorm:"embedded"`
}
var DB *gorm.DB
func connectDB() error {
var err error
spec := "slumberuser:password@tcp(localhost:3306)/slumber"
DB, err = gorm.Open("mysql", spec+"?parseTime=true&loc=UTC&charset=utf8")
DB.LogMode(true) // Print SQL statements
//defer DB.Close()
if err != nil {
return err
}
return nil
}
// cd tests
// go test -run TestGormEmbed
func TestGormEmbed(t *testing.T) {
if err := connectDB(); err != nil {
t.Errorf("error connecting to db %v", err)
}
values := []interface{}{&A{}, &B{}}
for _, value := range values {
DB.DropTable(value)
}
if err := DB.AutoMigrate(values...).Error; err != nil {
panic(fmt.Sprintf("No error should happen when create table, but got %+v", err))
}
DB.Save(&A{X: "AX1", Y: "AY1"})
DB.Save(&A{X: "AX2", Y: "AY2"})
DB.Save(&B{X: "BX1", Y: "BY1"})
DB.Save(&B{X: "BX2", Y: "BY2"})
//select * from `as` join `bs`;
// # x,y,x,y
// # AX1,AY1,BX1,BY1
// # AX2,AY2,BX1,BY1
// # AX1,AY1,BX2,BY2
// # AX2,AY2,BX2,BY2
var abs []AB
DB.Select("*").
Table("as").
Joins("join bs").
Find(&abs)
for _, ab := range abs {
fmt.Println(ab.A, ab.B)
}
// if it worked it should print
//{AX1 AY1} {BX1 BY1}
//{AX2 AY2} {BX1 BY1}
//{AX1 AY1} {BX2 BY2}
//{AX2 AY2} {BX2 BY2}
// but actually prints
//{BX1 BY1} {AX1 AY1}
//{BX1 BY1} {AX2 AY2}
//{BX2 BY2} {AX1 AY1}
//{BX2 BY2} {AX2 AY2}
}
我有一个名为 User 的结构:
type User struct {
Email string
Name string
}
和名为 UserDALModel 的结构:
type UserDALModel struct {
gorm.Model
models.User
}
gorm 模型如下所示:
type Model struct {
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time `sql:"index"`
}
这可以使 UserDALModel 与 gorm 模型和用户模型嵌套,因此输出将是:
{
ID
CreatedAt
UpdatedAt
DeletedAt
Email
Name
}
现在输出是:
{
Model: {
ID
CreatedAt
UpdatedAt
DeletedAt
}
User: {
Name
Email
}
}
根据 gorm 中的 this test,我认为您需要向结构中添加一个 embedded
标记。
type UserDALModel struct {
gorm.Model `gorm:"embedded"`
models.User `gorm:"embedded"`
}
如果需要,您还可以指定前缀 embedded_prefix
。
我找到了答案:
type UserModel struct {
Email string
Name string
}
type UserDALModel struct {
gorm.Model
*UserModal
}
------------------------------
user := UserModel{"name", "email@email.com"}
userDALModel := UserDALModel{}
userDal.UserModal = &user
注意在同一列中嵌入两个结构:
package tests
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"testing"
)
type A struct {
X string
Y string
}
type B struct {
X string
Y string
}
type AB struct {
B B `gorm:"embedded"` // Embedded struct B before struct A
A A `gorm:"embedded"`
}
var DB *gorm.DB
func connectDB() error {
var err error
spec := "slumberuser:password@tcp(localhost:3306)/slumber"
DB, err = gorm.Open("mysql", spec+"?parseTime=true&loc=UTC&charset=utf8")
DB.LogMode(true) // Print SQL statements
//defer DB.Close()
if err != nil {
return err
}
return nil
}
// cd tests
// go test -run TestGormEmbed
func TestGormEmbed(t *testing.T) {
if err := connectDB(); err != nil {
t.Errorf("error connecting to db %v", err)
}
values := []interface{}{&A{}, &B{}}
for _, value := range values {
DB.DropTable(value)
}
if err := DB.AutoMigrate(values...).Error; err != nil {
panic(fmt.Sprintf("No error should happen when create table, but got %+v", err))
}
DB.Save(&A{X: "AX1", Y: "AY1"})
DB.Save(&A{X: "AX2", Y: "AY2"})
DB.Save(&B{X: "BX1", Y: "BY1"})
DB.Save(&B{X: "BX2", Y: "BY2"})
//select * from `as` join `bs`;
// # x,y,x,y
// # AX1,AY1,BX1,BY1
// # AX2,AY2,BX1,BY1
// # AX1,AY1,BX2,BY2
// # AX2,AY2,BX2,BY2
var abs []AB
DB.Select("*").
Table("as").
Joins("join bs").
Find(&abs)
for _, ab := range abs {
fmt.Println(ab.A, ab.B)
}
// if it worked it should print
//{AX1 AY1} {BX1 BY1}
//{AX2 AY2} {BX1 BY1}
//{AX1 AY1} {BX2 BY2}
//{AX2 AY2} {BX2 BY2}
// but actually prints
//{BX1 BY1} {AX1 AY1}
//{BX1 BY1} {AX2 AY2}
//{BX2 BY2} {AX1 AY1}
//{BX2 BY2} {AX2 AY2}
}