Associations in GORM Golang
In Go, utilizing the GORM ORM, a common challenge arises when querying multiple entities with associated information. Let's delve into an example to illustrate this issue.
Consider structures representing a town and its associated places:
type Place struct { ID int Name string Town Town } type Town struct { ID int Name string }
Assuming a database with the following sample data:
places table | towns Table | |||||
---|---|---|---|---|---|---|
id | name | town_id | id | name | ||
1 | Place1 | 1 | 1 | Town1 | ||
2 | Place2 | 1 | 2 | Town2 |
To retrieve all places along with their corresponding towns, one might attempt the following query:
db := gorm.Open("sqlite3", "./data.db") defer db.Close() places := []Place{} db.Find(&places)
However, the result would yield:
[{1 Place1 {0 }} {2 Mares Place2 {0 }}]
Notice that the corresponding town information is missing. To rectify this, we need to specify the foreign key in the Place struct as TownID:
type Place struct { ID int Name string Description string TownID int Town Town }
To obtain the expected result, one could opt for the following approach:
db.Find(&places) for i, _ := range places { db.Model(places[i]).Related(&places[i].Town) }
This would indeed produce the desired result, but it suffers from an n 1 problem, as it triggers an additional database query for each place.
A more efficient solution involves utilizing Preloads:
db.Preload("Town").Find(&places)
This concise approach results in the following optimized database queries:
SELECT * FROM "places" [0.92ms] SELECT * FROM "towns" WHERE ("id" in ('1'))
By utilizing Preloads, we ensure that associated town information is retrieved in a single database query, thereby optimizing performance and eliminating the n 1 problem.
The above is the detailed content of How to Efficiently Query Associated Entities in GORM?. For more information, please follow other related articles on the PHP Chinese website!