xorm多表连接查询

得意时要看淡,失意时要看开。不论得意失意,切莫大意;不论成功失败,切莫止步。志得意满时,需要的是淡然,给自己留一条退路;失意落魄时,需要的是泰然,给自己觅一条出路xorm多表连接查询,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

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"`
}

数据库表为user表,group表分别包含结构体字段。如果连接查询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)

debug的时候可以看到,连接查询的灭个表都赋值到对应的结构体中了:

在这里插入图片描述

在这里插入图片描述

xorm通过结构体将sql查询的结果转化为层次分明的结构体数据,使数据更有层次感,热不是二维表全部展示,在程序中也方便赋值。

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

如下直接序列化返回json字符时没有显示同名的,应为同名的都不显示:

在这里插入图片描述

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/156133.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!