小工具      在线工具  汉语词典  css  js  c++  java

xorm多表连接查询

# xorm,sql,xorm 额外说明

收录于:152天前

SQL的连接查询可以将多个表的数据查询出来,形成一个中间表。在sql中为JOIN关键字。最常用的是LEFT JOIN,RIGHT JOIN,INNER JOIN,OUTER JOIN

xorm框架是一个基于go语言的ORM框架,也支持连接查询。由于xom和原生sql查询也支持基于xorm方法的查询,因此本文将基于两种不同的方法进行比较。

select order_item.id,order_item.order_id,order_item.product_name,order_item.product_id,order_item.product_area_id,order_item.card_type,order_item.card_num,order_item.container_name
,order_item.container_id,order_item.using_cpu,order_item.using_ram,order_item.video_memory,order_item.free_data_disk,order_item.expand_data_disk,order_item.max_cuda_version,order_item.container_name
,order_item.charge_mode,order_item.rent_start_time,order_item.rent_end_time,order_item.deleted_at,order_item.created_at,order_item.updated_at
,order_main.id as oid,order_main.customer_id as ocustomer_id ,order_main.order_amount as order_amount
from order_item LEFT JOIN order_main on order_item.order_id = order_main.id where order_main.customer_id = '1970' and order_main.order_id = '1'

如上面所示为一个LEFT JOIN的左连接查询,可以看到使用sql语句,需要将所有的字段通过表名.字段名列举出来,当然如果保证所有的字段都不同名,直接*也可以。

可见这样写sql比较麻烦,如果放到go里面就更臃肿了。

err = MasterDB.SQL("select * from (select financial_flow.id as fid ,financial_flow.number as number,financial_flow.customer_id as customer_id,financial_flow.customer_name as customer_name,financial_flow.type,financial_flow.recharge_way as recharge_way,financial_flow.money,financial_flow.operator_id as operator_id, order_item.id,order_item.order_id,order_item.product_name,order_item.product_id,order_item.product_area_id,order_item.card_type,order_item.card_num,order_item.container_name ,order_item.container_id,order_item.container_state,order_item.using_cpu,order_item.using_ram,order_item.video_memory,order_item.free_data_disk,order_item.expand_data_disk,order_item.max_cuda_version from order_item LEFT JOIN financial_flow on financial_flow.number = order_item.order_id ) as a RIGHT JOIN order_main on a.order_id = order_main.id limit ?,?", paginator.curPage, paginator.perPage).Find(&result)

代码会变成这样,可读性和可维护性都很差:

在这里插入图片描述

由于数据库的限制,所有数据只能以二维表的格式展示,因此没有层次结构,没有层次结构,不便于阅读。然而,程序中的数据结构是多样的、层次化的。例如,Go的结构可以很好地与数据库的数据连接。

xorm 中使用结构来表达连接关系。一个结构就是一个表,有多少个连接的表就有多少个兄弟结构。

官网案例:

//结构体1
type Group struct {
    
    Id int64
    Name string
}

//结构体2
type User struct {
    
    Id int64
    Name string
    GroupId int64 `xorm:"index"`
}

数据库表是用户表,组表包含结构字段。如果连接查询sql为:

select group.id as gid,group.name as gname,user.id as uid , user.name as uname,user.group_id as group_id from group LEFT JOIN user on group.id = user.group_id

由于两个表同名了很多字段,因此还需要使用as重命名,这样在查询的过程中有需要一个新的结构体赋值。显然这样是很不方便的。

Xorm根据结构体特点设计了一种新的赋值方式,将结构体进行嵌套,即使名称属于不同的结构体也不会发生冲突。

type UserGroup struct {
    
    User `xorm:"extends"`
    Group `xorm:"extends"`
}

使用嵌套表示连接查询的结果,必须使用xorm的tag并有extends关键字。

xorm提供了Join方法实现连接,其有三个参数engine.Table("user").Join("INNER", "group", "group.id = user.group_id")

第一个参数为连接类型,第二个参数为连接表,第三个参数为on的条件。而且Join的返回值还是engine仍是过程量,可通过Get或者Find方法查询结果。

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的第二个参数只是相关表的条件。

案件:

type Order2GpuServer struct {
    
	OrderMain     `xorm:"extends"`
	OrderItem `xorm:"extends"`
	Product      `xorm:"extends"`
	Node         `xorm:"extends"`
}
//订单对象
var order2GpuServers []models.Order2GpuServer
session := MasterDB.Join("LEFT", "order_item", "order_main.id = order_item.order_id")
session = session.Join("LEFT", "product", "order_item.product_id = product.id")
session = session.Join("LEFT", "node", "product.node_id = node.id")
session.Find(&order2GpuServers)

调试时可以看到连接查询中的所有表都被分配到相应的结构体中:

在这里插入图片描述

在这里插入图片描述

XORM通过结构将SQL查询的结果转换为层次结构数据,使数据更加具有层次性。并不是所有的数据都以二维表格的形式展示,而且在程序中赋值也方便。

虽然xorm框架在程序中以结构体i的形式保存了中间量的数据,但是当持久化和离开程序时,数据会变成二维的形式,即全部显示在一起,这样如果有是同名的名字,就会产生冲突,xorm策略不会显示同名的字段。

如下直接序列化返回JSON字符时,不会显示同名字符。应该是不显示同名的字符:

在这里插入图片描述

如果需要显示,则需要创建一个新的结构体,并通过连接返回的结构体依次赋值:

在这里插入图片描述
这样通过结构体.字段名来来获取不同个字段的值。

Join("","","")改变查询的方式为第一个参数LEFT,RIGHT,INNER,OUTER.

. . .

相关推荐

额外说明

K8S云原生渗透实践2

实战目标介绍 Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的一种机制。 如今,很多云原生产

额外说明

若依如何区分不同环境下的配置文件?

当在多配置文件中,需要切换配置文件时,通常的做法都是修改激活的文件名称,而[email protected]@是配合maven profile进行选择不同配置文件进行启动,可以避免修改文件,而在maven打包是

额外说明

Mybatis一级缓存和二级缓存的区别

区别 1.一级缓存 Mybatis的一级缓存是指SQLSession,一级缓存的作用域是SQlSession, Mabits默认开启一级缓存。 在同一个SqlSession中,执行相同的SQL查询时;第一次会去查询数据库,并写在缓存中,第二次会直接从缓存

额外说明

SQL Server根据数据库表自动生成insert语句并批量添加

实际工作中,两个数据库不在同一台服务器上,又需要复制数据库表时,可以在需要复制的数据库中创建下面的存储过程。 CREATE PROCEDURE [dbo].[OutputData] @tablename sysname,

额外说明

剑指向Offer 20。代表数值的字符串(自动机状态转换)

题目:请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、“5e2”、"-123"、“3.1416”、"-1E-16"、“0123"都表示数值,但"12e”、“1a3.14”、“1.2.3”、"±5"及"12e+5.4"

额外说明

【Unity ShaderGraph】| 如何快速制作一个 马赛克效果 实战

前言 【Unity ShaderGraph】| 如何快速制作一个 马赛克效果 实战 一、效果展示 二、马赛克效果 四、应用实例 前言 本文将使用Unity 的ShaderGraph制作一个马赛克的效果,可以直接拿到项目中使用。 对ShaderGraph还

额外说明

《零基础安装 Oracle 数据库》单机系列 ④ 一键快速安装 Oracle 19C 数据库

目录 前言 安装 下载项目 安装软件 下载 Oracle 安装包 安装 编辑 vagrant.yml 文件 开始安装 使用方式 连接主机 关闭主机 开启主机 销毁主机 写在最后 前言 很多朋友吐槽我的脚本不会用,看不懂,哎,一言难尽!于是,我将 [vag

额外说明

Weka学习笔记01:初探Weka世界

文章目录 一、Weka概述 二、下载Weka 三、安装Weka 四、启动Weka (一)Weka探索器 (二)Weka实验环境 (三)Weka知识流环境 (四)Weka工作台 (五)Weka命令行界面 五、Weka探索器 (一)探索器主界面 (二)Wek

额外说明

《天天数学》连载25:一月二十五日

格言作者:奥古斯丁(公元354年11月13日 - 公元430年8月28日),又名希波的奥古斯丁(Augustine of Hippo),天主教译为“圣奥斯定”,出生于古罗马帝国统治下的北非努米底亚,是一名摩尼教徒,同时也是基督教早期神学家,教会博士,以及

额外说明

在 SQL 中计算总行数的百分比

如何查看每种水果的订单占订单总数的百分比?事实上,在 SQL 中计算行百分比有三种标准方法。分别是: 1.使用 OVER() 子句 2.使用子查询 3.使用公用表表达式,或 CTE OVER() 子句 OVER 子句主要与窗口函数一起使用,用于确定将查询

ads via 小工具