### Join的使用
- Join(string,interface{},string)
第一個參數為連接類型,當前支持INNER, LEFT OUTER, CROSS中的一個值,第二個參數為表名,可以為字符串或者bean,第三個參數為連接條件。
以下將通過示例來講解具體的用法:
假如我們擁有兩個表user和group,每個User只在一個Group中,那么我們可以定義對應的struct
~~~
type Group struct {
Id int64
Name string
}
~~~
~~~
type User struct {
Id int64
Name string
GroupId int64 `xorm:"index"`
}
~~~
OK。問題來了,我們現在需要列出所有的User,并且列出對應的GroupName。利用extends和Join我們可以比較優雅的解決這個問題。代碼如下:
~~~
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。
~~~
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標記吧,代碼如下:
~~~
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個或更多表用法類似,如:
~~~
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的第二個參數只是被關聯表的條件。
~~~
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})
~~~