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

xorm多表连接查询

# xorm,sql,xorm 额外说明

收录于:18天前

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.

. . .

相关推荐

额外说明

解决采集文章防盗链图片不显示的问题(java)

在互联网上采集数据做应用时,我们经常会遇到目标网站图片有防盗链,导致采集文章中的图片在应用中无法预览,通常解决这个问题有2个办法: 1、采集的时候将图片下载到自己的服务器上,然后将图片路径替换为自己的图片路径,缺点是存储资源太大(费用太高),采集慢; 2

额外说明

redis高级: redisTemplate 修改默认的jdk序列化方式/StringRedisTemplate

目录 场景: 使用springboot自带的redistemplate 连接redis 效果: \xac\xed\x00\x05t\x00\x07auther1 方式一:(源码中可以看到 粘贴到需要的方法内) 方式二:  写一个配置类(简单)  ====

额外说明

【Unity优化篇】| Unity3D场景 常用优化策略,遮挡剔除、层消隐距离技术 和 LOD多层次细节

- 博客主页:https://xiaoy.blog.csdn.net - 本文由 呆呆敲代码的小Y 原创,首发于 CSDN- - 学习专栏推荐:Unity系统学习专栏 - 游戏制作专栏推荐:游戏制作 -Unity实战100例专栏推荐:Unity 实战10

额外说明

【Mybatis】常见面试题:处理表与表之间的关系:多对一,一对多

表的员工与部门有对应关系,实体类之间也有对应的关系 关系映射 多对一 方式一:级联方式处理映射关系 方式二:使用association处理映射关系 方式三:分步查询 一对多 方式一:collection 方式二:分步查询 多对一 在员工实体类中加入实体类

额外说明

springboot 缓存一致性常用解决方案

前言 多级缓存在微服务的架构设计中可谓随处可见,多级缓存作为提升系统高并发的常规手段,在各类大中小型的系统设计中都有体现; 下图是一张简单的服务端多级缓存设计示意图,多级缓存的常用解决方案,像ehcache + redis,或caffeine + spr

额外说明

TIDB - TIDB集群的扩容和缩容及TIUP指令说明

一、TIUP工具简介 前面介绍了使用TIUP搭建TIDB集群,本篇文章详细介绍下使用TIUP对集群进行扩容和缩容。 在面对双十一这种流量突峰的场景,我们平常的TIDB集群有可能承受不住,因此需要提前进行扩容,例如增加tidb-server,以增加TIDB

额外说明

彻底研究StringBuilder

 上一篇《 彻底研究String》介绍了String类型的一些性质。.NET对String的优化,能高效安全的完成一些操作,但正是这些优化导致了在进行某些操作时会占用大量的资源,如拼接字符串、修改字符串等等,高效地完成这些操作的替代类型是StringBu

额外说明

【GoWeb项目-个人Blog】个人Blog开篇

1个人blog网站 一直想开发一个属于自己的Blog,以前也尝试开发,但是后来就不了了之了,现在终于来了,这次把开发过程给记录下来。同时记录开发过程中的问题。加油吧!- 第一篇主要就是项目结构搭建和读取配置文件 注意:项目结构后期可能会更新 -1.1 项

额外说明

【Jmeter】报错解决:JedisException: Could not return the broken resource to the pool

一、报错详情 (1)报错场景 使用 Jmeter 插件 Redis Data Set 配置连接 Redis 数据池时,运行出现报错 (2)报错日志

额外说明

PostgreSQL【SQL 01】根据条件更新字段值或追加信息STRPOS(string, substring)函数使用及LIKE函数对比

1.需求说明 项目中有这样一个需求,根据条件标记数据,需要完成的内容如下: 对符合条件的数据进行标记; 无值则使用标记值; 有值则判断是否包含当前标记,包含则不处理,不包含则追加。 2.SQL编程 话不多说,上SQL: UPDATE targetTabl

ads via 小工具