2011-09-07 18 views
6

私はORM - Object Relational Mappingのファンであり、私は過去1年半の間、Railsと共に使用してきました。それ以前には、JDBCを使用して生のクエリを作成し、データベースをストアドプロシージャを使用して大量に実行することに使用します。 ORMを使って、私は最初はcoach.managermanager.coachesのようなものをやっていて、とても簡単で読みやすいものでした。オブジェクトリレーショナルマッピングの短所

しかし時間がたつにつれ、数多くの団体が這い上がっていて、私はa.b.c.dをやっていました。その背後には、あらゆる方向から質問が送られていました。レールとルビーでは、ガベージコレクタはナットし、非常に複雑なページをロードするのに苦労しました。私はこのORMスタイルのコードを単純なStoredプロシージャで置き換える必要があり、私が見た結果は膨大でした。 50秒間かかっていたページには2秒しかかかりません。

この大きな違いは、ORMを使用し続けるべきですか?生のクエリと比較して重大なオーバーヘッドがあることは明らかです。

一般に、Hibernate、ActiveRecordのようなORMフレームワークを使用する一般的な落とし穴は何ですか?

+0

遅延フェッチを使用していますか?基本的に 'ORM'はあなたが言う通りにロードします... –

+0

@Petar Minichev:ORMが私に許可しているすべての種類のフェッチを行っているので、それに直接的な答えは言えません。どこでもトレードオフがあります – bragboy

答えて

5

私はあなたが既にORMソフトウェアに関連した大きなトレードオフを特定していると思います。手作業で行っていたことの一般化された実装を提供しようとする抽象化の新しいレイヤーを追加するたびに、パフォーマンス/効率の一部が失われます。

a.b.c.dなどの複数の関係をトラバースすることは、ほとんどのORMソフトウェアが途中の.ごとに独立したデータベースクエリを実行するため、非効率的になる可能性があります。しかし、私はあなたがORMを完全になくすべきであるとは確信していません。ほとんどのORMソリューション(または少なくとも確実にHibernate)では、単一のデータベース操作で必要なものを正確に返すことができるカスタムクエリを指定できます。これは、あなたの専用SQLほど高速です。

本当に問題は、ORMレイヤーが背後でどのように働いているかを理解し、a.b.c.dのようなものが簡単に書くことができるということです。一般的なルールとして、私はいつも最も簡単なアプローチをとって出発し、それが理にかなっている場所に最適化されたクエリを書いています。

12

ORMは単なるツールです。正しく使用しないと、結果が悪くなります。

フェッチ・ジョインまたはプロジェクションを使用した専用のHQL/criteria問合せを使用して、ページに表示する必要がある情報をできるだけ少なくする必要はありません。これは、専用のSQL照会と同じくらい時間がかかります。

もちろん、IDですべてを取得し、生成するクエリの数を認識せずにオブジェクトをナビゲートすると、読み込み時間が長くなります。キーは、ORMがシーンの背後で何をするかを正確に把握し、適切かどうか、別の戦略を採用する必要があるかどうかを判断することです。

3

さまざまなタスクに適切なツールを使用する必要があります。

たとえば、CRUD操作では、HibernateなどのORMフレームワークは開発をスピードアップし、十分に機能します。許容可能なパフォーマンスを達成するために必要な調整が必要な場合もあります。あなたが私たちに詳細を提供してくれなかったので、あなたの仕事(Hibernateで50秒かかったもの)はHibernateで正しく実行できませんでした。

一方、例えば何十万ものレコードを含む一括操作は、Hibernateが大きなパフォーマンス上の不利益を被ることなく実行することが期待されるタスクのタイプではありません。

1

私はPetarと一緒に、レイジーフェッチに関するあなたのコメントからです。オブジェクトa.b.c.dからのhtmlテーブルの塗りつぶしフィールドがあるとします。フレームワークが何千回もデータベースをラウンドトリップさせる(おそらくもっと多くの場合)可能性があります。この場合のORMの欠点は、ドキュメントを徹底的に読む必要があることです。ほとんどのフレームワークは遅延型フェッチを無効にし、データセットをバインドする独自の処理ロジックを追加することをサポートしています。

ほとんどのORMは、あなた自身を書くつもりのものよりも間違いなく優れているということです。あなたは、定型文の巨大なライブラリを維持したり、同じコードを何度も何度も繰り返し書いたりすることに腹を立てるでしょう。

2

すでに言及したように、ORMは単なるツールであり、あなたはそれを良いか悪いかに使うことができます。

ORMの最も一般的なパフォーマンス問題の1つは、1 + Nクエリの問題です。これは、各オブジェクトの追加オブジェクトをリストからロードすることによって発生します。これは、リストの各要素に対して1対nの関連エンティティを賢くフェッチすることによって発生します。この処理では、HQLクエリを使用して、投影でフィールドを指定したり、1対nの関係を遅延にマーキングしたりします。

いつでも、パフォーマンスを向上させるためにORMが何をしているかを正確に把握する必要があります。バックグラウンドでどのような操作が行われているかを理解していないことは、災害への道です(不要で誤って書かれた回避策のため、コードを分析するのが遅く、バグがあり、難しい)。

0

私たちは現在、転送オブジェクトとデータアクセスオブジェクトをJPAに明確に分離して、独自のデータストア層からの切り替えを検討しています。私たちはジェネレータを使ってTO、DAO、およびSQL DDLをdocbook形式のドキュメントから作成しました。これにより、ドキュメント、データベース構造、生成されたJavaクラスからのすべてのものが、常にデータベース自体の優れたドキュメントと同期しています。

  1. 彼らは管理 エンティティ内に置かれてはならないので、外部キーの参照がそうで輸入、いくつかの特別な クエリとのために使用することはできません。私たちはJPAを使用することにより、これまでに発見された何

    。 JPAはそこでターゲットクラスのみを許可します。

  2. 一部のユーザーセッションスコープへのアクセスは不可能にまで困難です。私たち はまだいくつかのPrePersistメソッドでユーザIDをカラム 'userWhoLastMadeAnUpdate'に取得する手がかりがありません。
  3. ORMで非常に簡単なもの、つまり「クラス マッピング」はまったく機能しません。 HalDateTime (http://sourceforge.net/projects/haldatetime/)を社内で使用しています。 特にクライアントにあります。 HalDateTimeはサポートしていますが、JPAで直接マッピングすることは可能です( )。 JPAの制限 のため、エンティティでは2つのフィールドを使用する必要があります。
  4. JPAはいずれかのXMLファイルを使用してマッピングを記述します。だから 少なくとも2つのファイルにJavaのクラスとデータベースの間の関係 を理解するために見なければならない。そして、XMLファイルは大規模なアプリケーションには巨大な になります。
  5. ORMは、Javaクラス自体にアノテーションを提供します。だから その関係を学び理解するのが簡単です。しかし、 には、クライアント層のすべてのデータベースの内容が表示されます( は、適切なレイヤリングを完全に破棄します)。
  6. クリーンな データベース構造の近くにとどまるように制限する必要があります。それ以外の場合は、 がORMによるクエリとステートメントの混乱を招くことになります。
  7. SQL に近いクエリ言語を提供するORMを使用します(ここではJPAはかなり受け入れられるようです)。 ORM誘導言語 は、大きなアプリケーションを本当に高価にすることをサポートします。