2012-08-10 58 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秒。