2012-08-10 62 views
1

我在我的hibernate映射XML文件中有一個子選擇查詢(如下所示)。這樣做的目的是設置一個基本的SQL查詢,然後通過Criteria API添加各種限制。我顯示的數據可以進行排序,篩選和搜索,支持頁面調整,因此Criteria API對此非常有用。Hibernate子選擇Criteria API:MySql性能低下

<class name="className" table="tableName"> 
    <subselect> 
     select   x.col1   AS  ID, 
         c.col2   AS  a 
         .... 
     from   table1   x, 
         table2   y 
     where   x.id   =  y.id 
         .... 
         .... 
    </subselect> 
    <id name="ID" column="ID"/> 
    <property name="a" column="a"/> 
    ... 
    ... 
</class> 

,然後Java代碼會做這樣的事情

標準C = sessionFactory.getCurrentSession()個createCriteria(tableName.class)加上限制。 c.add(Restrictions.allEq(m)); //其中m是包含列過濾器的哈希映射

但是,似乎使用subselect來聲明基本查詢在MySQL中導致非常差的性能。 Hibernate將基本查詢放入子查詢中,該子查詢位於外部查詢的FROM子句中,該子查詢具有額外的限制。所以,爲了清楚起見,Hibernate創建了一個類似於A的查詢,而我想要的查詢是B,即我不想要子查詢,因爲它會殺死性能。

A: select _tmp.*       B: select t1.col1, 
    from (           t1.col2 
      select t1.col1,     from table1 t1, 
        t1.col2       table2 t2 
      from table1 t1,    where t1.id = t2.id 
        table2 t2    and  t1.col1 = 'blah' 
      where t1.id = t2.id    order by t1.col desc 
      ... 
     ) _tmp 
    where _tmp.col1 = 'blah' 
    order by _tmp.col2 desc 

所以我的問題是如何創建Hibernate中基本的查詢,而無需使用子查詢,讓我使用Criteria API?獲取Hibernate運行查詢B而不是查詢A的最佳方式是什麼?

據我所知,我可以在映射文件中創建命名查詢並加載它們,但是加載了一個查詢,雖然允許我添加某些限制,但它不像Criteria那樣好,因爲它不允許選項排序等...

那麼,有沒有除了使用任何其他選項要麼

<hibernate-mapping> 
<class name="" table=""> 
    <subselect></subselect> 
</class> 
</hibernate-mapping> 

or 
<hibernate-mapping> 
    <sql-query name=""> 
    <return-scalar column="col" type="string"/> 
    </sql-query> 
</hibernate-mapping> 

作爲第一個選項,通過使用子查詢的降低性能,而第二個選項不允許我(到最好的我的知識?)使用Criteria API。

回答

1

我有一個解決方案,所以我在這裏添加它作爲參考。

我的要求是使用Hibernate從多個表中檢索數據並使用Criteria API過濾結果集。作爲Hibernate和Criteria的新手,我選擇了當時最簡單的選項,即手工製作一些原始SQL,將數據集中在一起並使用Criteria過濾數據。使用子查詢是我知道在加載手工製作的SQL語句以進一步修改Criteria函數時的唯一方法。這在功能方面運行良好,但如上所述,在針對MySQL運行時表現很差。

我沒有意識到我能用Criteria做的事情是使用別名來限制關聯。所以我放棄了原始SQL,並使用Hibernate檢索我的父數據對象,並使用Criteria Aliases在所有必需的關聯上添加限制。該方法在100ms內執行,相比之下5秒。