Association Query
When querying data involving multiple tables, using joins can be inefficient for large datasets. In GoFrame, model association queries are provided to simplify such operations.
Taking dept
, emp
, and hobby
tables as examples: each department can have multiple employees, each employee belongs to one department, and each employee has one hobby.
Query all employees and associate their departments
- Modify
entity.Emp
, include association information
internal/model/entity/emp.go
type Emp struct {
Id uint `json:"id"` // ID
DeptId uint `json:"dept_id"` // Department ID
Name string `json:"name"` // Name
Gender int `json:"gender"` // Gender: 0=male 1=female
Phone string `json:"phone"` // Contact phone
Email string `json:"email"` // Email
Avatar string `json:"avatar"` // Photo
Dept *Dept `orm:"with:id=dept_id" json:"dept"`
}
- Use
With
to specify the associated model query
var emps []*entity.Emp
err = dao.Emp.Ctx(ctx).With(entity.Dept{}).Scan(&emps)
Without specifying With
, the Dept
in the query results will be nil
.
Query all employees and associate departments and hobbies
- Modify
entity.Emp
, include association information
internal/model/entity/emp.go
type Emp struct {
Id uint `json:"id"` // ID
DeptId uint `json:"dept_id"` // Department ID
Name string `json:"name"` // Name
Gender int `json:"gender"` // Gender: 0=male 1=female
Phone string `json:"phone"` // Contact phone
Email string `json:"email"` // Email
Avatar string `json:"avatar"` // Photo
Dept *Dept `orm:"with:id=dept_id" json:"dept"`
Hobby *Hobby `orm:"with:emp_id=id" json:"hobby"`
}
- Use
With
to specify the required associations
var emps []*entity.Emp
err = dao.Emp.Ctx(ctx).With(entity.Dept{}, entity.Hobby{}).Where("dept_id", 101).Scan(&emps)
Alternatively, use WithAll
to associate all.
var emps []*entity.Emp
err = dao.Emp.Ctx(ctx).WithAll().Where("dept_id", 101).Scan(&emps)
Query departments and associate each department's employees
- Modify
entity.Dept
, include association information
internal/model/entity/dept.go
// Dept is the golang structure for table dept.
type Dept struct {
Id uint `json:"id"` // ID
Pid uint `json:"pid"` // Parent department ID
Name string `json:"name"` // Department name
Leader string `json:"leader"` // Department leader
Phone string `json:"phone"` // Contact phone
Emps []*Emp `orm:"with:dept_id=id" json:"emps"`
}
- Query
var depts []*entity.Dept
err = dao.Dept.Ctx(ctx).With(entity.Emp{}).Scan(&depts)
When performing association queries, modifications are made directly in the entity classes. However, these classes are usually generated by tools and should not be modified under normal circumstances. Therefore, when conducting association queries, it's advisable to define custom structs, retaining only the necessary fields (the fields used for association must exist).
type MyDept struct {
g.Meta `orm:"table:dept"`
Id uint `json:"id"` // ID
Name string `json:"name"` // Department name
Leader string `json:"leader"` // Department leader
Phone string `json:"phone"` // Contact phone
}
type MyEmp struct {
g.Meta `orm:"table:emp"`
Id uint `json:"id"` // ID
DeptId uint `json:"dept_id"` // Department ID
Name string `json:"name"` // Name
Phone string `json:"phone"` // Contact phone
Dept *MyDept `orm:"with:id=dept_id" json:"dept"`
}
var emps []*MyEmp
err = dao.Emp.Ctx(ctx).With(MyDept{}).Scan(&emps)
When defining custom structs, use g.Meta
and orm
tags to specify the corresponding data table.
Here's the translated markdown into English:
```markdown
# Association Query
When querying data involving multiple tables, joins can be inefficient for large datasets. GoFrame provides model association queries to simplify complex multi-table joins.
Using `dept`, `emp`, and `hobby` tables as an example: each department can have multiple employees, each employee belongs to exactly one department, and each employee has one hobby.
**Query all employees and associate their departments**
- Modify `entity.Emp`, include association information
`internal/model/entity/emp.go`
```go
type Emp struct {
Id uint `json:"id"` // ID
DeptId uint `json:"dept_id"` // Department ID
Name string `json:"name"` // Name
Gender int `json:"gender"` // Gender: 0=male 1=female
Phone string `json:"phone"` // Contact phone
Email string `json:"email"` // Email
Avatar string `json:"avatar"` // Photo
Dept *Dept `orm:"with:id=dept_id" json:"dept"`
}
- Use
With
to specify the associated model query
var emps []*entity.Emp
err = dao.Emp.Ctx(ctx).With(entity.Dept{}).Scan(&emps)
If With
is not specified, the Dept
field in the query results will be nil
.
Query all employees and associate departments and hobbies
- Modify
entity.Emp
, include association information
internal/model/entity/emp.go
type Emp struct {
Id uint `json:"id"` // ID
DeptId uint `json:"dept_id"` // Department ID
Name string `json:"name"` // Name
Gender int `json:"gender"` // Gender: 0=male 1=female
Phone string `json:"phone"` // Contact phone
Email string `json:"email"` // Email
Avatar string `json:"avatar"` // Photo
Dept *Dept `orm:"with:id=dept_id" json:"dept"`
Hobby *Hobby `orm:"with:emp_id=id" json:"hobby"`
}
- Use
With
to specify the required associations
var emps []*entity.Emp
err = dao.Emp.Ctx(ctx).With(entity.Dept{}, entity.Hobby{}).Where("dept_id", 101).Scan(&emps)
Alternatively, use WithAll
to associate all.
var emps []*entity.Emp
err = dao.Emp.Ctx(ctx).WithAll().Where("dept_id", 101).Scan(&emps)
Query departments and associate each department's employees
- Modify
entity.Dept
, include association information
internal/model/entity/dept.go
// Dept is the golang structure for table dept.
type Dept struct {
Id uint `json:"id"` // ID
Pid uint `json:"pid"` // Parent department ID
Name string `json:"name"` // Department name
Leader string `json:"leader"` // Department leader
Phone string `json:"phone"` // Contact phone
Emps []*Emp `orm:"with:dept_id=id" json:"emps"`
}
- Query
var depts []*entity.Dept
err = dao.Dept.Ctx(ctx).With(entity.Emp{}).Scan(&depts)
When performing association queries, modifications are made directly in the entity classes. However, these classes are usually generated by tools and should not be modified under normal circumstances. Therefore, when conducting association queries, it's advisable to define custom structs, retaining only the necessary fields (the fields used for association must exist).
type MyDept struct {
g.Meta `orm:"table:dept"`
Id uint `json:"id"` // ID
Name string `json:"name"` // Department name
Leader string `json:"leader"` // Department leader
Phone string `json:"phone"` // Contact phone
}
type MyEmp struct {
g.Meta `orm:"table:emp"`
Id uint `json:"id"` // ID
DeptId uint `json:"dept_id"` // Department ID
Name string `json:"name"` // Name
Phone string `json:"phone"` // Contact phone
Dept *MyDept `orm:"with:id=dept_id" json:"dept"`
}
var emps []*MyEmp
err = dao.Emp.Ctx(ctx).With(MyDept{}).Scan(&emps)
When defining custom structs, use g.Meta
and orm
tags to specify the corresponding data table.