在处理庞大的数据表时,我应该如何使用Hibernate Mapping

Har*_*ars 4 java sql hibernate

问题定义:
我有一个数据库表,包含大量数据(超过100,000行),表结构就像

AppID  DocID  DocStatus 
1      100    0
1      101    1    
2      200    0    
2      300    1
Run Code Online (Sandbox Code Playgroud)

每个applicationID可能有数千个文档,我必须获取状态为0的文档的计数和状态为1的文档的数量按applicationID分组.

当我使用hibernate映射这个对象时,由于大量的表数据,它会占用大量的堆内存.

如何使用Hibernate查询实现此目的? 或者我应该使用SQL查询或存储过程吗?

注意:我的Web应用程序位于JAVA/Tapestry框架中并使用Hibernate 3.数据库是SQL Server 2012.

Luk*_*der 16

每次遇到以数据为中心的问题(而不是以Java域为中心的问题)时,都应该直接使用SQL.您的数据库将比Java代码快得多,因为计算可以与数据紧密相关,而不是通过线路将所有数据传输到内存中.另请参阅此博客文章中的"2.处理内存中的数据".

您可以直接使用JDBC,或使用本机查询,或使用您选择的任何第三方SQL库(如MyBatisjOOQ)来实现此目的.

使用以下任何查询都可以轻松解决您的问题:

使用GROUP BY

SELECT [AppID], [DocStatus], count(*)
FROM [MyTable]
GROUP BY [AppID], [DocStatus]
Run Code Online (Sandbox Code Playgroud)

关于SQLFiddle的示例

使用嵌套选择

SELECT [AppID],
       (SELECT count(*) FROM [MyTable] [t2]
        WHERE [t1].[AppID] = [t2].[AppID]
        AND [DocStatus] = 0) [Status_0],
       (SELECT count(*) FROM [MyTable] [t2]
        WHERE [t1].[AppID] = [t2].[AppID]
        AND [DocStatus] = 1) [Status_1]
FROM [MyTable] [t1]
GROUP BY [AppID]
Run Code Online (Sandbox Code Playgroud)

关于SQLFiddle的示例

使用SUM()

SELECT [AppID],
       SUM(IIF([DocStatus] = 0, 1, 0)) [Status_0],
       SUM(IIF([DocStatus] = 1, 1, 0)) [Status_1]
FROM [MyTable] [t1]
GROUP BY [AppID]
Run Code Online (Sandbox Code Playgroud)

关于SQLFiddle的示例

使用PIVOT

SELECT [AppID], [0], [1]
FROM (
  SELECT [AppID], [DocStatus]
  FROM [MyTable]
) [t]
PIVOT (count([DocStatus]) FOR [DocStatus] IN ([0], [1])) [pvt]
Run Code Online (Sandbox Code Playgroud)

关于SQLFiddle的示例