1

hibernateを使用する際に発生するオーバーヘッドを克服するために、hibernateからplain JDBCにシフトバックしています。hibernateに関連付けられたセッションを処理する方法を知りたいと思いました。すべてのセッションがに置き換えられるように、PlainJDBCに戻すにはどうすればよいですか。 JDBC接続。セッションを接続に置き換えると、これらの概念に精通しておらず、正しい方向に進んでいるかどうかわからないため、プレーンJDBCに戻るという考えが間違っている場合はお知らせください。

4

3 に答える 3

3

私は、何百万ものレコードのバッチ挿入など、ハイパフォーマンス タスクで Hibernate を広範囲に使用してきました。問題は Hibernate ではなく、使用方法にあります。

特に、Hibernate を永続的な状態マネージャーとして使用しないでください。生の SQL の上の薄いレイヤーとして使用すれば、パフォーマンスについて文句を言うことはありません。

  1. 常に優先StatelessSessionします (操作以外の必要なものすべてで機能しますsave)`;
  2. 遅延フェッチを使用しないでください。すべてに明示的な結合を使用してください。
  3. オブジェクト全体を決してフェッチしないでください。必要なものを正確にフェッチするには SELECT を使用してください。
  4. 単一のステートメントで可能な限りフェッチし、n+1 の選択は絶対に避けてください。
  5. 大きな結果セットの場合は、 、またはlistを使用しないでください。iteratescroll

リストは続きますが、これが現時点で私が思いついたものです。

直接の質問に関しては、アプリケーションによって異なります。Spring アプリケーションの場合は、その宣言型トランザクション管理を使用する必要があります。基本的に、数行の XML 構成を配置するだけで、DAO コードにオープンな DataSource を使用できるようになり、ユーザー側で管理する必要はありません。

もっと生のことをしているのであれば、素晴らしい BoneCP などの接続プール ライブラリを必ず使用してください。そこから接続を取得し、後で明示的な管理なしで接続を返します。

最後に、必要最小限の安全でスケーラブルでないアプローチが本当に必要な場合は、JDBC ドライバーから直接接続を作成できます。このアプローチは実際には学業専用であり、生産に値する最小のプロジェクトであってもお勧めできません。

于 2012-10-25T11:30:30.510 に答える
1

Hibernate セッションは JDBC 接続以上のものです。これには、複数のそのような接続 (通常は JDBC 接続インスタンスをリサイクルする JDBC 接続プールを介して管理される)、接続され、上記のセッションおよびその他のもの (キャッシュなど) によって管理される一連のエンティティが含まれます。

Hibernate を削除し、すべてを JDBC API のみで行うことは、Hibernate セッション インスタンスを 1 つまたは複数の JDBC 接続に置き換えてから、Hibernate コードを類似の JDBC API 呼び出しに複製するだけではありません。それだけを行うと、Hibernate のすべての利点 (冗長なコードの削減、より高いレベルの抽象化など) を失い、JDBC の利点 (より少ないヒープ メモリの使用、メソッド呼び出しの減少 (そうです、Hibernate の Javassist マジックを使用しても、場合によってはパフォーマンスに影響します)、データベース インタラクションのきめ細かな制御など)。

私のアドバイスは、最初にアプリが抱えている問題 (明らかに Hibernate によるもの) を実際に調べて、少なくとも主要な問題については、Hibernate を取り除かないとアプリを最適化できないかどうかを最初に確認することです。はい、Hibernate は重くなり、メモリを消費する可能性がありますが、多くの場合、パフォーマンスの問題はフレームワークの不適切な使用に起因します (1 つのクエリで必要なすべての関連付けられたエンティティをフェッチしていると確信していますか、または Hibernate に make させますか?バックグラウンドで隠し結合または疑似結合を行っていますか?データベース側でデータ操作を行っていますか?それとも、必要以上に一般的な Hibernate クエリを実行してデータを取得した後に Java コードでその一部を行っていますか?など。 )

本当に Hibernate を取り除く必要がある場合 (標準 SQL ではなく、カスタム フラットを介して大量のデータをインポートする MySQL の機能のように、Hibernate ではアクセスできないデータベースの非常に特殊な機能を使用する必要がある場合があります) -file 形式) 次に、それを置き換えるもの (プレーン JDBC、または EclipseLink などの他の ORM) が問題に取り組み、よりパフォーマンスの高い方法で解決できることを確認してください。コードの再構築を開始する前に、小さな POC を実行してこれらをテストすると、時間を大幅に節約できます。

于 2012-10-25T11:30:59.197 に答える
0

Marko と Shivan のアドバイスに耳を傾けることを強くお勧めしますが、hibernate を使用して接続/セッション/トランザクションを管理し、多くのオーバーヘッドを発生させずに SQL クエリを実行することができます。

ハイバネート セッションから SQL を実行すると、簡単な Google 検索でこれが得られました。

http://www.informit.com/guides/content.aspx?g=java&seqNum=575

以前の回答の両方に同意しますが、純粋な SQL を実行する道を本当に進みたい場合は、2 つの理由からこのオプションを検討します。

1) セッションはすでに開始されています。休止状態ですべてのエンティティをロードしない場合、休止状態がそれほど多くのオーバーヘッドを生成する方法がわかりません。

2)問題が速度であり、以前に遭遇したオーバーヘッドではない場合、これを実装して、問題のある領域でネイティブ SQL をすばやく実行し、休止状態の ORM グッズをすべて所定の位置に保持できます。

そうは言っても、休止状態のドキュメントを掘り下げることもお勧めします。私はいくつかの高性能ソリューションに休止状態を使用して大きな成功を収めました。最初はニュアンスに取り組むのが難しいかもしれませんが、休止状態 (または少なくとも JPA 標準に準拠するもの) を使用する利点は、今後のスケーラビリティに関してそうしないことのコストをはるかに上回ります。

于 2012-10-25T15:57:21.500 に答える