如何将数据库记录加载到子结构中?

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

How to load database records into sub structs?

问题

正在玩GO/Beego框架,并尝试查询数据库以将一些记录加载到结构体中。

以下是重要的代码:

type User struct {
	UserId        int64     `orm:"pk"`
	FirstName     string    `orm:"null" valid:"MinSize(2);MaxSize(150)"`
	LastName      string    `orm:"null" valid:"MinSize(2);MaxSize(150)"`
	Email         string    `valid:"Required;MinSize(2);MaxSize(150);Email" required:"true" description:"user email address"`
	Password      string    `valid:"Required;MaxSize(60)" required:"true" description:"user plain text password" json:"-"`
	AccessLevel   uint64    `json:"-"`
	AuthKey       string    `json:"-"`
	Status        int       `json:"-"`
	DateAdded     time.Time `orm:"-" json:"-"`
	LastUpdated   time.Time `orm:"-" json:"-"`

	// relations
	Profile *UserProfile `orm:"rel(one)" json:"-"`
}

type UserProfile struct {
	UserId          int64  `orm:"pk"`
	Company         string `orm:"null" valid:"MinSize(2);MaxSize(150)"`
	VatNumber       string `orm:"null" valid:"MinSize(2);MaxSize(150)"`
	Website         string `orm:"null" valid:"MinSize(2);MaxSize(150)"`
	Phone           string `orm:"null" valid:"MinSize(2);MaxSize(150);Mobile"`
	Address1        string `orm:"null" valid:"MinSize(2);MaxSize(255)"`
	Address2        string `orm:"null" valid:"MinSize(2);MaxSize(255)"`
	City            string `orm:"null" valid:"MinSize(2);MaxSize(150)"`
	State           string `orm:"null" valid:"MinSize(2);MaxSize(150)"`
	Zip             string `orm:"null" valid:"MinSize(4);MaxSize(15)"`
	Country         string `orm:"null" valid:"MinSize(2);MaxSize(150)"`
	ConfirmationKey string `orm:"null" valid:"Length(40)" json:"-"`

	// relations
	User *User `orm:"reverse(one)" json:"-"`
}

func GetAllUsers() []User {
	o := orm.NewOrm()
	var users []User
	sql := `
	SELECT user.*, user_profile.* 
	   FROM user
	   INNER JOIN user_profile ON user_profile.user_id = user.user_id 
	WHERE 1`
	_, err := o.Raw(sql).QueryRows(&users)
	if err != nil {
		beego.Error(err)
	}
	beego.Info(users)
	return users
}

上述代码的问题是,在调用GetAllUsers()时,嵌入在User中的结构体Profile不会被填充,所以我该如何使嵌入的结构体也被填充?

我还尝试使用以下方式获取用户:

o.QueryTable("user").Filter("status", STATUS_ACTIVE).RelatedSel("Profile").All(&users)

它会生成一个类似于以下的SQL查询:

SELECT T0.`user_id`, T0.`first_name`, T0.`last_name`, T0.`email`, T0.`password`, T0.`access_level`, T0.`auth_key`, T0.`status`, T0.`profile_id`, T1.`user_id`, T1.`company`, T1.`vat_number`, T1.`website`, T1.`phone`, T1.`address1`, T1.`address2`, T1.`city`, T1.`state`, T1.`zip`, T1.`country`, T1.`confirmation_key` FROM `user` T0 INNER JOIN `user_profile` T1 ON T1.`user_id` = T0.`profile_id` WHERE T0.`status` = ? LIMIT 1000

我不知道它是从哪里得到的在profile_id列上的连接,因为它甚至不存在,我也不确定如何指定正确的列进行连接,似乎它是从结构体名称中获取的。此外,我不喜欢无法指定要选择的内容。

非常感谢任何提示,我相信我错过了一些简单的东西。

谢谢。

英文:

Playing around with GO/Beego Framework and trying to query the database to load some records into a struct.

Bellow is the important code:

type User struct {
UserId int64 `orm:"pk"`
FirstName string `orm:"null" valid:"MinSize(2);MaxSize(150)"`
LastName string `orm:"null" valid:"MinSize(2);MaxSize(150)"`
Email string `valid:"Required;MinSize(2);MaxSize(150);Email" required:"true" description:"user email address"`
Password string `valid:"Required;MaxSize(60)"  required:"true" description:"user plain text password" json:"-"`
AccessLevel uint64 `json:"-"`
AuthKey string `json:"-"`
Status int `json:"-"`
DateAdded time.Time `orm:"-" json:"-"`
LastUpdated time.Time `orm:"-" json:"-"`
// relations
Profile *UserProfile `orm:"rel(one)" json:"-"` // OneToOne relation
}
type UserProfile struct {
UserId  int64 `orm:"pk"` // doesn't work without a PK, doesn't make sense, it's a fk...
Company string `orm:"null" valid:"MinSize(2);MaxSize(150)"`
VatNumber string `orm:"null" valid:"MinSize(2);MaxSize(150)"`
Website string `orm:"null" valid:"MinSize(2);MaxSize(150)"`
Phone string `orm:"null" valid:"MinSize(2);MaxSize(150);Mobile"`
Address1 string `orm:"null" valid:"MinSize(2);MaxSize(255)"`
Address2 string `orm:"null" valid:"MinSize(2);MaxSize(255)"`
City string `orm:"null" valid:"MinSize(2);MaxSize(150)"`
State string `orm:"null" valid:"MinSize(2);MaxSize(150)"`
Zip string `orm:"null" valid:"MinSize(4);MaxSize(15)"`
Country string `orm:"null" valid:"MinSize(2);MaxSize(150)"`
ConfirmationKey string `orm:"null" valid:"Length(40)" json:"-"`
// relations
User *User `orm:"reverse(one)" json:"-"` // Reverse relationship (optional)
}
func GetAllUsers() []User {
o := orm.NewOrm()
var users []User
sql := `
SELECT user.*, user_profile.* 
FROM user
INNER JOIN user_profile ON user_profile.user_id = user.user_id 
WHERE 1`
_, err := o.Raw(sql).QueryRows(&users)
if err != nil {
beego.Error(err)
}
beego.Info(users)
return users
}

Now the problem with above is that upon calling GetAllUsers() the embed struct from User, that is Profile, doesn't get populated, so how would i go so that embed structs are also populated?

I have also tried to get the users with:

o.QueryTable("user").Filter("status", STATUS_ACTIVE).RelatedSel("Profile").All(&users)

which produces a sql query like:

SELECT T0.`user_id`, T0.`first_name`, T0.`last_name`, T0.`email`, T0.`password`, T0.`access_level`, T0.`auth_key`, T0.`status`, T0.`profile_id`, T1.`user_id`, T1.`company`, T1.`vat_number`, T1.`website`, T1.`phone`, T1.`address1`, T1.`address2`, T1.`city`, T1.`state`, T1.`zip`, T1.`country`, T1.`confirmation_key` FROM `user` T0 INNER JOIN `user_profile` T1 ON T1.`user_id` = T0.`profile_id` WHERE T0.`status` = ? LIMIT 1000

And i don't know from where it came up with the join on profile_id column since that doesn't even exists and i am not sure how to specify the right column to join, seems it takes it from the structure name. Also, i don't like the fact that there isn't a way to specify what to select.

Any hint is highly appreciated, i am sure it's something simple that i miss.

Thanks.

答案1

得分: 1

以下是翻译好的内容:

https://github.com/astaxie/beego/issues/384 有一个相关的讨论,但是是中文的。关键代码如下:

type User struct {
  Id   int
  Name string
}

type Profile struct {
  Id   int
  Age  int
}

var users []*User
var profiles []*Profile
err := o.Raw(`SELECT id, name, p.id, p.age FROM user
    LEFT OUTER JOIN profile AS p ON p.id = profile_id WHERE id = ?`, 1).QueryRows(&users, &profiles)
英文:

https://github.com/astaxie/beego/issues/384 has a relative talk, but it's Chinese.The key is below:

type User struct {
Id   int
Name string
}
type Profile struct {
Id   int
Age  int
}
var users []*User
var profiles []*Profile
err := o.Raw(`SELECT id, name, p.id, p.age FROM user
LEFT OUTER JOIN profile AS p ON p.id = profile_id WHERE id = ?`, 1).QueryRows(&users, &profiles)

huangapple
  • 本文由 发表于 2015年3月13日 23:03:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/29035566.html
匿名

发表评论

匿名网友

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

确定