TownID必须指定为外键。该
Place结构如下所示:
type Place struct { ID int Name string Description string TownID int Town Town}现在有不同的方法来处理此问题。例如:
places := []Place{}db.Find(&places)for i, _ := range places { db.Model(places[i]).Related(&places[i].Town)}这肯定会产生预期的结果,但是请注意日志输出和触发的查询。
[4.76ms] SELECt * FROM "places"[1.00ms] SELECt * FROM "towns" WHERe ("id" = '1')[0.73ms] SELECt * FROM "towns" WHERe ("id" = '1')[{1 Place1 {1 Town1} 1} {2 Place2 {1 Town1} 1}]输出是预期的结果,但是这种方法有一个根本性的缺陷,请注意,对于每个位置,都需要执行另一个产生
n +1问题的db查询。这可以解决问题,但随着场所数量的增加,将很快失去控制。
事实证明,使用预加载是一种 很好的 方法。
db.Preload("Town").Find(&places)就是这样,生成的查询日志是:
[22.24ms] SELECt * FROM "places"[0.92ms] SELECt * FROM "towns" WHERe ("id" in ('1'))[{1 Place1 {1 Town1} 1} {2 Place2 {1 Town1} 1}]这种方法只会触发两个查询,一个查询所有地点,一个查询所有有地点的城镇。这种方法可以很好地扩展地方和城镇的数量(在所有情况下都只有两个查询)。



