Skip to main content

关联查询

多表数据联查时可以用连接,但是数据量大时连接效率不高,GoFrame中提供了模型关联查询,可以简化一些多表联查操作。

deptemphobby三个表为例,每个部门可以有多个员工,每个员工只有一个部门,每个员工对应一条爱好。

查询所有员工,并关联查询出其所在部门

  • 修改entity.Emp,加入关联信息

internal/model/entity/emp.go

type Emp struct {
Id uint `json:"id" ` // ID
DeptId uint `json:"dept_id" ` // 所属部门
Name string `json:"name" ` // 姓名
Gender int `json:"gender" ` // 性别: 0=男 1=女
Phone string `json:"phone" ` // 联系电话
Email string `json:"email" ` // 邮箱
Avatar string `json:"avatar" ` // 照片

Dept *Dept `orm:"with:id=dept_id" json:"dept"`
}
  • 使用With指定关联模型查询
var emps []*entity.Emp
err = dao.Emp.Ctx(ctx).With(entity.Dept{}).Scan(&emps)

不用With指定关联的话,查询出的结果中Deptnil

查询所有员工,并关联查询出部门与爱好

  • 修改entity.Emp,加入关联信息

internal/model/entity/emp.go

type Emp struct {
Id uint `json:"id" ` // ID
DeptId uint `json:"dept_id" ` // 所属部门
Name string `json:"name" ` // 姓名
Gender int `json:"gender" ` // 性别: 0=男 1=女
Phone string `json:"phone" ` // 联系电话
Email string `json:"email" ` // 邮箱
Avatar string `json:"avatar" ` // 照片

Dept *Dept `orm:"with:id=dept_id" json:"dept"`
Hobby *Hobby `orm:"with:emp_id=id" json:"hobby"`
}
  • 使用With指定需要关联的内容
var emps []*entity.Emp
err = dao.Emp.Ctx(ctx).With(entity.Dept{}, entity.Hobby{}).Where("dept_id", 101).Scan(&emps)

也可以用WithAll关联所有

var emps []*entity.Emp
err = dao.Emp.Ctx(ctx).WithAll().Where("dept_id", 101).Scan(&emps)

查询部门,关联查询出每个部门的员工

  • 修改entity.Dept,加入关联信息

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" ` // 上级部门ID
Name string `json:"name" ` // 部门名称
Leader string `json:"leader" ` // 部门领导
Phone string `json:"phone" ` // 联系电话

Emps []*Emp `orm:"with:dept_id=id" json:"emps"`
}
  • 查询
var depts []*entity.Dept
err = dao.Dept.Ctx(ctx).With(entity.Emp{}).Scan(&depts)

上述关联查询直接在实体类里面修改,但实体类里的内容是用工具自动生成的,一般情况下不要修改。所以在进行关联查询时,需要重新自定义结构体,只需要保留需要查询的字段即可(用于关联的字段必须存在)

type MyDept struct {
g.Meta `orm:"table:dept"`
Id uint `json:"id" ` // ID
Name string `json:"name" ` // 部门名称
Leader string `json:"leader" ` // 部门领导
Phone string `json:"phone" ` // 联系电话
}

type MyEmp struct {
g.Meta `orm:"table:emp"`
Id uint `json:"id" ` // ID
DeptId uint `json:"dept_id" ` // 所属部门
Name string `json:"name" ` // 姓名
Phone string `json:"phone" ` // 联系电话

Dept *MyDept `orm:"with:id=dept_id" json:"dept"`
}

var emps []*MyEmp
err = dao.Emp.Ctx(ctx).With(MyDept{}).Scan(&emps)

自定义结构体时,需要用g.Metaorm标签指定对应的数据表