1 回答
TA贡献2039条经验 获得超8个赞
首先,没有办法直接做到这一点,例如,在struct上声明一些类型的字段,并让数据库驱动程序自动反序列化它们,因为两端的数据模型是根本不同的:数据库是关系的(假设这是因为你使用的是sqlx),而Go是面向对象的结构。因此,这将是ORM(对象关系映射,因此得名)的工作。但是假设您还不想使用ORM。XY
其次,无论现有 FK 约束如何,您使用的 SQL 查询仅返回表中的数据。它不会神奇地返回其他数据。因此,您要么查询数据库两次,要么必须查询两个表:fixtureJOIN
SELECT
f.id,
t1.id as home_team_id,
t1.name as home_team_name,
t2.id as away_team_id,
t2.name as away_team_name
FROM
fixture f
JOIN team t1 ON t1.id = f.home
JOIN team t2 ON t2.id = f.away
请注意有助于区分列名的别名。这将返回必要的数据字段。现在,您可以使用第三个桥接结构来正确扫描从数据库获取的行,并使用它初始化您的主结构:as
// Here I'm using (a slice of) anonymous structs,
// but you can declare a named one instead.
bridge := []struct {
FixtureId int64 `db:"id"`
HomeTeamId int64 `db:"home_team_id"`
HomeTeamName string `db:"home_team_name"`
AwayTeamId int64 `db:"away_team_id"`
AwayTeamName string `db:"away_team_name"`
}{}
err := db.SelectContext(ctx, &bridge, query)
if err != nil {
// handle err...
}
mystructs := make([]Fixture, len(bridge))
for i, b := range bridge {
mystructs[i] = Fixture{
ID: b.FixtureId,
Home: Team{
ID: b.HomeTeamId,
Name: b.HomeTeamName,
},
Away: Team{
ID: b.AwayTeamId,
Name: b.AwayTeamName,
},
}
}
其他不太方便的替代方案是:
用于获取结果并循环访问它,初始化结构。(记得在完成后关闭,释放资源)sqlx.Queryx(ctx, query)*sqlx.RowsFixtureRows
让父结构实现(示例Fixturesql.Scanner)
- 1 回答
- 0 关注
- 146 浏览
添加回答
举报
