This repository has been archived on 2022-04-14. You can view files and clone it, but cannot push or open issues or pull requests.
manual-zh-CN/chapter-05/5.join.md
2015-11-26 13:27:53 +08:00

114 lines
3.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

### Join的使用
* Join(string,interface{},string)
第一个参数为连接类型当前支持INNER, LEFT OUTER, CROSS中的一个值
第二个参数为string类型的表名表对应的结构体指针或者为两个值的[]string表示表名和别名
第三个参数为连接条件。
以下将通过示例来讲解具体的用法:
假如我们拥有两个表user和group每个User只在一个Group中那么我们可以定义对应的struct
```Go
type Group struct {
Id int64
Name string
}
```
```Go
type User struct {
Id int64
Name string
GroupId int64 `xorm:"index"`
}
```
OK。问题来了我们现在需要列出所有的User并且列出对应的GroupName。利用extends和Join我们可以比较优雅的解决这个问题。代码如下
```Go
type UserGroup struct {
User `xorm:"extends"`
Name string
}
func (UserGroup) TableName() string {
return "user"
}
users := make([]UserGroup, 0)
engine.Join("INNER", "group", "group.id = user.group_id").Find(&users)
```
这里我们将User这个匿名结构体加了xorm的extends标记实际上也可以是非匿名的结构体只要有extends标记即可这样就减少了重复代码的书写。实际上这里我们直接用Sql函数也是可以的并不一定非要用Join。
```Go
users := make([]UserGroup, 0)
engine.Sql("select user.*, group.name from user, group where user.group_id = group.id").Find(&users)
```
然后我们忽然发现我们还需要显示Group的Id因为我们需要链接到Group页面。这样又要加一个字段算了不如我们把Group也加个extends标记吧代码如下
```Go
type UserGroup struct {
User `xorm:"extends"`
Group `xorm:"extends"`
}
func (UserGroup) TableName() string {
return "user"
}
users := make([]UserGroup, 0)
engine.Join("INNER", "group", "group.id = user.group_id").Find(&users)
```
这次,我们把两个表的所有字段都查询出来了,并且赋值到对应的结构体上了。
这里要注意User和Group分别有Id和Name这个是重名的但是xorm是可以区分开来的不过需要特别注意UserGroup中User和Group的顺序如果顺序反了则有可能会赋值错误但是程序不会报错。
这里的顺序应遵循如下原则:
结构体中extends标记对应的结构顺序应和最终生成SQL中对应的表出现的顺序相同。
还有一点需要注意的如果在模板中使用这个UserGroup结构体对于字段名重复的必须加匿名引用
对于不重复字段,可以`{{.GroupId}}`,对于重复字段`{{.User.Id}}`和`{{.Group.Id}}`
这是2个表的用法3个或更多表用法类似
```Go
type Type struct {
Id int64
Name string
}
type UserGroupType struct {
User `xorm:"extends"`
Group `xorm:"extends"`
Type `xorm:"extends"`
}
users := make([]UserGroupType, 0)
engine.Table("user").Join("INNER", "group", "group.id = user.group_id").
Join("INNER", "type", "type.id = user.type_id").
Find(&users)
```
同时在使用Join时也可同时使用Where和Find的第二个参数作为条件Find的第二个参数同时也允许为各种bean来作为条件。Where里可以是各个表的条件Find的第二个参数只是被关联表的条件。
```Go
engine.Table("user").Join("INNER", "group", "group.id = user.group_id").
Join("INNER", "type", "type.id = user.type_id").
Where("user.name like ?", "%"+name+"%").Find(&users, &User{Name:name})
```
当然,如果表名字太长,我们可以使用别名:
```Go
engine.Table("user").Alias("u").
Join("INNER", []string{"group", "g"}, "g.id = u.group_id").
Join("INNER", "type", "type.id = u.type_id").
Where("u.name like ?", "%"+name+"%").Find(&users, &User{Name:name})
```