1

HibernateマッピングXMLファイルに(以下のような)副選択クエリがあります。これの目的は、CriteriaAPIを介してさまざまな制限が追加される基本的なSQLクエリを設定することです。ページネーションをサポートして並べ替え、フィルタリング、検索できるデータを表示しているので、CriteriaAPIはこれに非常に役立ちます。

<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

だから私の質問は、Criteria APIを使用できるようにする副選択を使用せずにHibernateで基本的なクエリを作成するにはどうすればよいですか?クエリAではなくクエリBを実行するHibernateを取得するための最良の方法は何ですか?

マッピングファイルに名前付きクエリを作成して読み込むことができることは理解していますが、クエリを読み込むと、特定の制限を追加できますが、並べ替えなどのオプションが許可されないため、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>

最初のオプションはサブクエリの使用によってパフォーマンスを低下させ、2番目のオプションは(とにかく私の知る限りでは?)CriteriaAPIを使用することを許可しないためです。

4

1 に答える 1

1

私には解決策があるので、参考のためにここに追加します。

私の要件は、Hibernateを使用して複数のテーブルからデータを取得し、CriteriaAPIを使用して結果セットをフィルタリングすることでした。HibernateとCriteriaにかなり慣れていないので、当時最も簡単だと思ったオプションを選択しました。それは、生のSQLを手作りしてデータをまとめ、Criteriaを使用してそのデータをフィルタリングすることでした。副選択の使用は、Criteria関数によるさらなる修正のために手作りのSQLステートメントをロードするときに私が知っていた唯一の方法でした。これは機能的には問題なく機能しましたが、上記で詳しく説明したように、MySQLに対して実行した場合のパフォーマンスは非常に低くなりました。

Criteriaでできることに気づかなかったのは、エイリアスを使用して関連付けに制限を設けることです。そこで、生のSQLを捨て、Hibernateを使用して親データオブジェクトを取得し、CriteriaAliasesを使用して必要なすべての関連付けに制限を追加しました。このメソッドは、5秒と比較して100ミリ秒未満で実行されます。

于 2012-08-13T14:21:51.217 に答える