Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用联接对排序数据进行休眠分页_Java_Hibernate_Pagination - Fatal编程技术网

Java 使用联接对排序数据进行休眠分页

Java 使用联接对排序数据进行休眠分页,java,hibernate,pagination,Java,Hibernate,Pagination,我们目前正在研究加速应用程序的方法,其中很大一部分与实体列表(实际上是一个表)有关 参数和要求 该列表的参数和要求如下(我将尝试在此处仅提及相关参数和要求): 列表中最多可以有500000行/实体 一次只显示其中的几个,我们将在这里使用分页 用户可以选择在列表中显示哪些列(因此我们不能提供单一的“静态”查询) 大多数列表列都是可排序和/或可筛选的 这些实体有一对多的关系,这些关系还提供了一些列表列 某些列表列可以包含多个值(这些值在单个单元格中显示为列表) 来自当前用户操作(如编辑、上传等)的

我们目前正在研究加速应用程序的方法,其中很大一部分与实体列表(实际上是一个表)有关

参数和要求

该列表的参数和要求如下(我将尝试在此处仅提及相关参数和要求):

  • 列表中最多可以有500000行/实体
  • 一次只显示其中的几个,我们将在这里使用分页
  • 用户可以选择在列表中显示哪些列(因此我们不能提供单一的“静态”查询)
  • 大多数列表列都是可排序和/或可筛选的
  • 这些实体有一对多的关系,这些关系还提供了一些列表列
  • 某些列表列可以包含多个值(这些值在单个单元格中显示为列表)
  • 来自当前用户操作(如编辑、上传等)的任何数据更新应尽快反映在列表中(即“立即”)
<> P>为了使模型更清晰,考虑下面的简化实体(如JPA)模型:

因为用户可以选择在运行时显示的列,所以我们动态地构建必要的查询。到目前为止,一切都很顺利

基本问题

我们面临的问题是涉及排序和筛选时的性能:我们当前的方法是将排序和筛选所需的所有数据加载到内存中,在内存中进行排序和筛选,然后保留排序ID列表和这些ID上的页面。我们知道这有点慢,但到目前为止,性能已经足够好,足以满足我们的管理层。但情况发生了变化,因为我们现在有更多的数据可供操作,性能要求也提高了

因此,我们正在研究改进所有数据adn排序和过滤的方法,而我们目前正在采用在数据库上进行排序和过滤的方法。我仍然会问这个(附带)问题:

  • 如何最好地对具有动态列和每个单元格可能有多个值的大量行进行分页
目前,我们正在使用Postgresql,如果可能的话,我们希望继续使用它,但如果一个不同的存储更适合我们,我们至少会检查一下

当前方法和问题(底部)

如上所述,我们目前正在尝试让数据库对数据进行排序、筛选和分页。可以使用两个查询:一个用于获取当前页面的行ID,另一个用于实际加载这些行的数据

由于挑战是第一个问题,我将集中讨论:

好的,我们可以在SQL中执行类似的操作(使用上面的car示例):

理论上,这个查询(虽然可能不完全正确)应该提供我们需要的结果,以确定要为当前页面加载哪些行

因为我们使用的是Hibernate(5.2 atm),所以我们希望使用HQL或标准来实现这一点。然而,Hibernate似乎不支持从上面的select语句中进行选择,因此这可能不是一种可行的方法。如果我们不得不退回到原生SQL或一种完全不同的方法,尽管如此,但我们更愿意让它与当前的基础设施一起工作

因此,问题是:

  • Hibernate5.x是否支持“从选择中选择”之类的功能
  • 当必须对多个关系进行排序和筛选时(即单个联接可能导致重复行),如何使用Hibernate进行分页

我在过去的雇主也有类似的要求,我们同样注意到,在较小的数据集下,数据库完全能够做到这一点;然而,即使是数据库也将面临一个转折点

我的解决方案是引入Hibernate搜索及其与ElasticSearch的集成,将搜索数据存储在NoSQL Lucene数据存储中,这对于基于unicode的文本查询和排序是绝对快速的,如您所述

这允许您继续使用现有的Hibernate ORM基础设施,并将这些附加组件以最小的工作量烘焙到您的体系结构中。集成是无缝的,当然值得投资,尤其是当您的数据集随着时间的推移不断增长时


我们处理的是1000万行,绝对没有性能问题。执行排序和分页的查询平均耗时不到100毫秒。

您可以使用HQL运行SQL查询,方法是将查询作为String@GauravSrivastav是的,我们知道如何执行SQL查询,如果没有更好的方法,我们将使用它。然而,由于查询可能变得非常复杂,并且是动态创建的,因此我们不希望必须访问实体的映射信息来提取构建此类查询所需的信息——如果Hibernate已经提供了我们可以使用的东西,则不必如此。您的模型有多复杂?通过使用数据库视图并将实体与之绑定,您可能会获得最佳性能。糟糕的是,您需要手工编写数据库视图(如果您开始支持新的RDBMS,可能还需要另一个版本)。好的是,实体会变得更简单,Hibernate生成性能差的SQL的机会也会减少。@Mick助记符模型非常复杂,有10多个表可以在多个级别上连接(比如实体->类别->文本)以及一些可以在运行时创建/添加的数据列,这些数据列在某种程度上是按照的建模的(有些人认为这是一种反模式,只用于实际需要它的部分)。@Mick助记符视图可能是我们模型的主要部分的一个选项,其结构在运行时是静态的。怎么
class Car {
  String manufacturer;
  String model;
  Date dateOfProduction;
  List<TyreSize> allowedTyreSizes;
  Set<Date> inspectionDates;
}
+==============+=======+=======+===============+=============+
| Manufacturer | Model | Prod. | Allowed Tyres | Inspections |
+==============+=======+=======+===============+=============+
| BMW          | 320d  |01/2016| - 225/40 R18  | - 01/07/16  |
|              |       |       | - 225/45 R17  | - 13/12/16  |
+--------------+-------+-------+---------------+-------------+
| Toyota       | Camry |09/2016| - 185/70 R13  | - 31/12/16  |
+--------------+-------+-------+---------------+-------------+ 
SELECT DISTINCT id FROM (
  SELECT id, ... FROM car c
    LEFT OUTER JOIN allowedtyresizes ats ON c.id = ats.car_id
    LEFT OUTER JOIN tyresizes ts ON ts.id = ats.tyresize_id
    ... //additional joins if required
    ORDER BY ... //apply any user-defined sorts
    WHERE ... //apply any user-defined filters (or maybe put them into the joins)
  )
  OFFSET ... //page offset
  LIMIT ...  //page size