如何在维护小结果集的同时从SQL中填充对象的列表属性? 问题描述

如何在维护小结果集的同时从SQL中填充对象的列表属性? 问题描述,sql,postgresql,join,mybatis,Sql,Postgresql,Join,Mybatis,对于Java应用程序中的PDF报告,我从PostgreSQL 9.6数据库查询各种数据。传递给报告的数据还包含列表,这些列表反过来包含其他列表。然而,总的来说,报告并没有包含那么多的值,值的数量大约在数百个 为了查询数据,我使用了一个包含多个连接的大型SQL语句(大约8个连接)来查询列表和列表中的列表的数据。但是,连接自然会导致输出中有许多行被复制。E、 g.以下查询: 挑选* 从值1、'item A',2、'item B'itemsid,标签 左连接值1,'子项A1',1,'子项A2',1,'

对于Java应用程序中的PDF报告,我从PostgreSQL 9.6数据库查询各种数据。传递给报告的数据还包含列表,这些列表反过来包含其他列表。然而,总的来说,报告并没有包含那么多的值,值的数量大约在数百个

为了查询数据,我使用了一个包含多个连接的大型SQL语句(大约8个连接)来查询列表和列表中的列表的数据。但是,连接自然会导致输出中有许多行被复制。E、 g.以下查询:

挑选* 从值1、'item A',2、'item B'itemsid,标签 左连接值1,'子项A1',1,'子项A2',1,'子项A3'子项SiteMid,项上的标签。id=子项。项id 左连接值1,'sub2Item A1',1,'sub2Item A2',1,'sub2Item A3'subitems2itemId,items上的标签。id=subitems2.itemId 只返回10行8个值,这很容易处理。但是,另一个子项表上的一个多连接(仅包含3个值)将包含28行,总共包含11个值:

挑选* 从值1、'item A',2、'item B'itemsid,标签 左连接值1,'子项A1',1,'子项A2',1,'子项A3'子项SiteMid,项上的标签。id=子项。项id 左连接值1,'sub2Item A1',1,'sub2Item A2',1,'sub2Item A3'subitems2itemId,items上的标签。id=subitems2.itemId 左连接值1,'子项目A1',1,'子项目A2',1,'子项目A3'子项目S3ItemId,项目标签。id=子项目S3.itemId 而且,每执行一次连接操作,行数都会快速增长。在我的帐户示例中,我同时编写的查询生成了大约50万行,仅用于一个只有几百个值的平均大小的报告。虽然我使用MyBatis从查询中构建列表,但效果很好,速度很慢,占用大量bandwith和内存,因此这实际上是一个问题

解决问题的思路 一个选择是使用MyBatis的嵌套选择功能,它允许我使用N+1查询自动检索列表。但是,某些视图上的联接需要对大型表进行分组和求和,这很慢,如果只查询一次视图,则使用这些视图中的数据填充两个列表的速度要快得多。 另一种可能是在Java中执行一些连接操作,分别从不同的表/视图中选择数据,然后从这些数据中填充对象的列表。虽然这会起作用,但它忽略了SQL的强大功能,我需要自己复制SQL的特性。 第三种可能是忽略SQL的表结构,构建层次结构,例如使用JSON:

选择 json_aggjsonb_build_对象 “id”,items.id, “subA”,subitems.list, “subB”,subitems2.list, “subC”,subitems3.list 后果 从值1、'item A',2、'item B'itemsid,标签 左连接 选择itemId,json\u标签列表 从…起 值1,'子项目A1',1,'子项目A2',1,'子项目A3'子项目中间,标签 按项目ID分组 items.id上的子项=subitems.itemId 左连接 选择itemId,json\u标签列表 从…起 值1,'子项目A1',1,'子项目A2',1,'子项目A3'子项目站点中间,标签 按项目ID分组 items.id上的subitems2=subitems2.itemId 左连接 选择itemId,json\u标签列表 从…起 值1,'子项目A1',1,'子项目A2',1,'子项目A3'子项目中间,标签 按项目ID分组 items.id上的subitems3=subitems3.itemId 后面的选项返回:

[{ id:1, 子项:[子项A1、子项A2、子项A3], 子项B:[子项A1、子项A2、子项A3], 分条款:[分条款A1、分条款A2、分条款A3] }, { id:2, subA:null, subB:null, subC:null }] JSON结果是我可以很容易地用Java再次解析的东西。在我看来,这个选项效率最高,因为它完全消除了数据重复,并且可以直接反序列化到一个已经具有正确结构的Java对象。然而,由于需要进行所有json_agg和jsonb_build_对象调用,因此它的可读性受到了轻微的损害

问题
我想我不是第一个遇到这个问题的人。那么还有其他选择吗?是否有一些公认的最佳实践来处理这个问题?我对可能选项的分析正确吗?

您不能用DBMS进行一些操作吗

如果您为一个平均大小的报告生成了超过50万行,我猜您正在检索一些数据并在Java代码中进行计算


您可以创建一些视图或聚合表来简化查询。

不,我根本不用Java进行任何计算。Java中唯一发生的事情就是将表格结果转换为树对象结构。当然,我可以在DBMS中构建树结构,这正是我上面介绍的JSON解决方案所做的 .