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")

相关推荐

  1. 【go】gorm\xorm\ent联查

    2024-07-16 10:56:01       52 阅读
  2. SQL两/关联查询--JOIN语句

    2024-07-16 10:56:01       62 阅读
  3. Mysql的联合查询

    2024-07-16 10:56:01       53 阅读
  4. gorm 使用sql方法

    2024-07-16 10:56:01       46 阅读
  5. SQL Server 联合更新方法

    2024-07-16 10:56:01       31 阅读
  6. MySQL联合查询&聚合函数应用实例

    2024-07-16 10:56:01       34 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-16 10:56:01       70 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-16 10:56:01       74 阅读
  3. 在Django里面运行非项目文件

    2024-07-16 10:56:01       62 阅读
  4. Python语言-面向对象

    2024-07-16 10:56:01       72 阅读

热门阅读

  1. 结合案例简单介绍无人驾驶汽车

    2024-07-16 10:56:01       21 阅读
  2. Super-Mario-Host(超级玛丽)靶机

    2024-07-16 10:56:01       24 阅读
  3. 大语言模型里的微调vs RAG vs模板提示词

    2024-07-16 10:56:01       23 阅读
  4. 低空经济迅猛发展的几个因素

    2024-07-16 10:56:01       21 阅读
  5. 第19集《修习止观坐禅法要》

    2024-07-16 10:56:01       17 阅读
  6. 将 Docker Engine 节点从 dockershim 迁移到 cri-dockerd

    2024-07-16 10:56:01       25 阅读
  7. 【WPF】图片剪裁-ImageCropping

    2024-07-16 10:56:01       22 阅读
  8. springboot集成MQTT实现消息接收

    2024-07-16 10:56:01       21 阅读