The link http://gorm.io/docs/preload.html talks about preloading in GORM, but I am unable to understand what this function does.
type User struct {
gorm.Model
Username string
Orders Order
}
type Order struct {
gorm.Model
UserID uint
Price float64
}
db.Preload("Username")
db.Preload("Orders").Find(&users)
Can someone explain what will these 2 statements do? What will be the output ?
Is it that preload
is used to cache the results?
First of all, this doesn't really do anything:
db.Preload("Username")
On the other hand, the following:
db.Preload("Orders").Find(&users)
Does do something. First it populates users
and then it populates []user.Orders
. On the comments on the page you linked you will find this, which shows what it does by query:
db.Preload("Orders").Find(&users)
//// SELECT * FROM users;
//// SELECT * FROM orders WHERE user_id IN (1,2,3,4);
So what does this really do? I can give you the technical answer, which you can easily find out by googling eager loading or I can give you an answer by example which I feel is simpler.
So let me explain this by example.
Say you have users, where each user can have multiple orders. This is a one to many relationship which can be defined like:
type User struct {
gorm.Model
Username string
Orders []Order
}
When you populate your users
slice like:
db.Find(&users)
//// SELECT * FROM users;
If you need to get all the orders for each user you can easily access user.Orders
but this would be empty anyway because it didn't get populated.
If we populate users
slice like:
db.Preload("Orders").Find(&users)
The user.Orders
will be populated by the orders of that user. This is an abstraction that makes dealing with relationships easier.
The ugly alternative would be:
db.Find(&users)
for user := range users {
db.Where("user_id", user.id).Find(&user.Orders)
}
It will also make more request to the database than necessary. (which is not good)
If your users has Posts and Comments and Orders then you can define and query it like this:
type User struct {
gorm.Model
Username string
Orders []Order
Comments []Comment
Posts []Post
}
db.Preload("Orders").Preload("Comments").Preload("Posts").Find(&users)
With just the code above you can now have access to the users data in different tables in the database.
I hope that helps.