我有一个结构Person
:如何映射m:n与切片场的关系?
type Person struct {
Id int64
Name string
Colors []string
}
应当从person
表中获取其数据:
id | name
---------
1 | Joe
2 | Moe
和person_color
表:
person_id | color
-----------------
1 | black
1 | blue
2 | green
通过SELECT p.id, p.name, pc.color FROM person AS p INNER JOIN person_color AS pc ON pc.person_id = p.id
我合并这两个表到:
id | name | color
-----------------
1 | Joe | black
1 | Joe | blue
2 | Moe | green
此刻,我能想到的唯一的事情是将手动映射颜色,同时遍历rows.Next()
(注:只是虚设码):
ps := make([]People, 0)
rows, err := db.Query("SELECT ...")
for rows.Next() {
var p Person
err := rows.Scan(&p.Id, &p.Name, &p.Color[0])
exists := false
for _, ps := range ps {
if ps.Id == p {
exists = true
ps.Color = append(ps.Color, p.Color)
}
}
if !exists {
ps = append(ps, p)
}
}
虽然这样的工作,这是很烦人因为映射到切片字段是一种常见操作。
有没有什么办法可以在sql或sqlx的所有切片字段上做出上述通用?
另一种通用的方法是拆分查询。查询名称并使用空的“颜色”创建“人物”对象。然后查询所有名称的所有颜色,并将其添加到人员。这种方法扩展到多个外键,或称为“切片字段”,因为你称它们为: – Andomar 2014-08-30 14:06:32
@Andomar嗯我认为使用另一个查询不会解决这个问题,因为你仍然需要以某种方式减少返回的行。目前我认为我们能做的最好的是一个'Peoples'类型,它有一个'Reduce()'方法,将所有'People'与相同的'People.Id'合并。但仍然怀疑对此有如此少的反应 - 对我来说似乎并不奇特:) – bodokaiser 2014-08-30 14:47:39
是的,这是一个[非常常见的问题](http://en.wikipedia.org/wiki/Object-relational_impedance_mismatch) 。作为一名老程序员,我的建议是不要花太多时间将数据从表格移动到对象。这个问题本身并不值得一提。 – Andomar 2014-08-30 15:35:26