# Join的使用
* Join(string,interface{},string)
第一个参数为连接类型,当前支持INNER, LEFT OUTER, CROSS中的一个值, 第二个参数为string类型的表名,表对应的结构体指针或者为两个值的[]string,表示表名和别名, 第三个参数为连接条件。
以下将通过示例来讲解具体的用法:
假如我们拥有两个表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})
~~~
当然,如果表名字太长,我们可以使用别名:
~~~
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})
~~~
- xorm
- 创建Orm引擎
- 定义表结构体
- 名称映射规则
- 前缀映射,后缀映射和缓存映射
- 使用Table和Tag改变名称映射
- Column属性定义
- 表结构操作
- 获取数据库信息
- 表操作
- 创建索引和唯一索引
- 同步数据库结构
- 导入导出SQL脚本
- SqlMap及SqlTemplate模板
- 初始化SqlMap配置文件及SqlTemplate模板
- SqlMap及SqlTemplate相关功能API
- SqlMap配置文件及SqlTemplate模板加密存储及解析
- 手动管理SqlMap配置及SqlTemplate模板
- 插入数据
- ORM方式插入数据
- 执行SQL命令插入数据
- 创建时间Created
- 查询和统计数据
- ORM方式查询和统计数据
- 查询条件方法
- 临时开关方法
- Get方法
- Find方法
- Join的使用
- Iterate方法
- Count方法
- Rows方法
- Sum系列方法
- Exist方法
- 子查询
- 执行SQL查询
- 执行SQL查询的11种常用方式
- 查询返回json或xml字符串
- 链式查询据操返回某条记录的某个字段的值
- SqlTemplateClient执行过程
- 关于数据库分页查询
- 更新数据
- ORM方式更新数据
- Update方法
- 乐观锁Version
- 更新时间Updated
- 执行SQL命令更新数据
- 删除数据
- ORM方式删除数据
- Delete方法
- 软删除Deleted
- 执行SQL命令删除数据
- 事务处理
- 简单事务模型
- 嵌套事务模型
- 八种事务类型及事务传播机制
- 简单事务相关API
- 嵌套事务相关API
- 嵌套事务示例代码
- 主从数据库(Master/Slave)读写分离
- 创建引擎组
- 负载策略
- 引擎组其他配置方法
- 数据库读写分离
- 批量混合SQL操作
- SQL Builder
- 缓存
- 事件
- 数据导出
- Dump数据库结构和数据
- 查询结果集导出csv、tsv、xml、json、xlsx、yaml、html
- 多Sheet页数据导出
- 日志
- 连接池
- xorm 工具
- 常见问题
- 感谢支持