gorm多表联合查询 Joins方法 LEFT JOIN , RIGHT JOIN , INNER JOIN, FULL JOIN 使用总结

gorm中多表联合查询,我们可以使用Joins来完成,这个Joins方法很灵活,我们可以非常方便的多多表进行联合查询, 我们先来看看这个方法的官方定义和使用示例:

Joins方法定义和使用示例

当然我们这里要说的使用方式是官方示例里面没有的,有的我们就不重复废话了。

从上面的方法定义我们可以看到,这个Joins的第一个参数query string 他就是一个查询字符串, 第二个参数是可变参数, 从这个参数定义就可以看出,这里的第一个参数query 就是我们需要进行多表链接的查询参数,这里的查询参数可以是任何的SQL支持的链接查询语句,如 LEFT JOIN , RIGHT JOIN ,  INNER JOIN, FULL JOIN等。

gorm中的这个Joins方法,我们可以直接将我们需要的链接方式和链接条件都写在这个查询字符串里面即可,如果有参数可以跟在后面,参数可以使用问号? 占位符方式 或者 @xxx 命名参数方式传递。

LEFT JOIN 左链接使用示例


// 获取用户拥有的角色ID和值的对象数组
func (s *roleSvc) GetRoleIdsValByUid(c *ginx.XContext, uid int32) ([]int64, error) {
	var roleIds []int64
	m := global.GetTx("sys_role c").Select("c.role_id")
	m = m.Joins("LEFT JOIN sys_user_role ur on ur.role_id = c.role_id")
	m = m.Joins("LEFT JOIN sys_user u on u.uid = ur.uid")
	m = m.Where("c.del_flag = '0' and u.del_flag = '0'")
	m = m.Where("ur.uid = ?", uid)
	err := m.Pluck("c.role_id", &roleIds).Error
	if err != nil {
		return nil, myerror.New("未查询到用户角色数据数据 " + err.Error())
	}
	return roleIds, nil
}

其他的链接方式使用都是一样的,只是不同的链接方式输出的结果不一样而已。

其语法一般为:  链接方式  表名 别名  ON 链接条件   如: LEFT JOIN sys_user u on u.uid = ur.uid

常用SQL JOIN的语义

  • LEFT JOIN:即使右表中没有匹配,也从左表返回所有的行 这个用得最多
  • RIGHT JOIN:即使左表中没有匹配,也从右表返回所有的行
  • INNER JOIN:如果表中有至少一个匹配,则返回行
  • FULL JOIN:只要其中一个表中存在匹配,则返回行

Gorm Joins链接代码参考


// Joins specify Joins conditions
//
//	db.Joins("Account").Find(&user)
//	db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzhu@example.org").Find(&user)
//	db.Joins("Account", DB.Select("id").Where("user_id = users.id AND name = ?", "someName").Model(&Account{}))
func (db *DB) Joins(query string, args ...interface{}) (tx *DB) {
	return joins(db, clause.LeftJoin, query, args...)
}

// InnerJoins specify inner joins conditions
// db.InnerJoins("Account").Find(&user)
func (db *DB) InnerJoins(query string, args ...interface{}) (tx *DB) {
	return joins(db, clause.InnerJoin, query, args...)
}

func joins(db *DB, joinType clause.JoinType, query string, args ...interface{}) (tx *DB) {
	tx = db.getInstance()

	if len(args) == 1 {
		if db, ok := args[0].(*DB); ok {
			j := join{
				Name: query, Conds: args, Selects: db.Statement.Selects,
				Omits: db.Statement.Omits, JoinType: joinType,
			}
			if where, ok := db.Statement.Clauses["WHERE"].Expression.(clause.Where); ok {
				j.On = &where
			}
			tx.Statement.Joins = append(tx.Statement.Joins, j)
			return
		}
	}

	tx.Statement.Joins = append(tx.Statement.Joins, join{Name: query, Conds: args, JoinType: joinType})
	return
}

总结

Gorm中官方只提供了2个相关的Join方法,一个就是Joins, 另外一个时 InnerJoins, 他们最终都调用的joins方法。 我们可根据我们的业务需求直接将我们需要的链接查询语句放到这里的query参数里面, gorm就会为我们生成对应的查询SQL。 需要注意的是,这里的Joins方法,如果我们指定了链接条件, 则这里就必须要手动指定链接方式,如.Joins("LEFT JOIN sys_user_role ur on ur.role_id = c.role_id")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值