web-dev-qa-db-ja.com

Hibernate、iBatis、Java EEまたはその他Java ORMツール

現在、大規模なエンタープライズアプリケーションを計画しています。私たちは、J2EEの苦痛を経験した後、休止状態を評価することに注力しています。

新しいJava= EE APIの方が簡単です。HibernateとiBatisについていくつか良い点も読んだことがあります。私たちのチームはどのフレームワークについてもほとんど経験がありません。

主に比較したい5つの比較ポイントがあります

  • 学習曲線/使いやすさ
  • 生産性
  • 保守性/安定性
  • パフォーマンス/スケーラビリティ
  • トラブルシューティングのしやすさ

J2EEの経験を持つ6人以下の開発者のチームを管理する場合、どのORMツールを使用しますか、またその理由は何ですか。

66
Kevin Williams

これを一読しましょう。最初に、私はこの主題について ORMまたはプレーンSQLを使用していますか? でいくつか書きました。特にあなたのポイントに取り組むために:

学習曲線/使いやすさ

IbatisはSQLについてです。 SQLを知っている場合、ibatisの学習曲線は取るに足らないものです。 Ibatisは、SQLに加えて次のようなことを行います。

  • グループ化;
  • 差別的なタイプ;そして
  • 動的SQL。

まだ学ぶ必要がありますが、最大のハードルはSQLです。

一方、JPA(Hibernateを含む)は、SQLから距離を置き、関係的な方法ではなくオブジェクトで物事を提示しようとします。しかし、ジョエルが指摘しているように、 抽象化は漏れやすい であり、JPAも例外ではありません。 JPAを実行するには、リレーショナルモデル、SQL、クエリのパフォーマンスチューニングなどについても知っておく必要があります。

Ibatisは、あなたが知っている、または学んでいるSQLを適用するだけですが、JPAは、それを構成する方法(XMLまたは注釈のいずれか)を知る必要があります。これにより、外部キー関係は、ある種の関係(1対1、1対多、または多対多)、タイプマッピングなどであることを理解することを意味します。

SQLを知っていれば、JPAの学習に対する障壁は実際にはもっと高いと言えます。そうしないと、JPAとの混合結果になり、しばらくの間SQLの学習を効果的に延期できます(ただし、無期限に延期されることはありません)。

JPAを使用すると、エンティティとその関係を設定すると、他の開発者はそれらを使用するだけでよく、JPAの構成に関するすべてを学ぶ必要はありません。これは利点になるかもしれませんが、開発者はエンティティマネージャー、トランザクション管理、管理対象オブジェクトと非管理対象オブジェクトなどについて知る必要があります。

JPAにも独自のクエリ言語(JPA-SQL)があり、SQLを知っているかどうかを知る必要があることに注意してください。 JPA-SQLがSQLでできることを実行できない状況を見つけるでしょう。

生産性

これは判断が難しいものです。個人的にはibatisの方が生産性が高いと思いますが、SQLにも本当に慣れています。 Hibernateの方が生産性が高いと主張する人もいますが、これはおそらくSQLに慣れていないことが原因の少なくとも一部です。

また、ログを有効にして、JPAプロバイダーが生成し、機能しているSQLを監視するときに、データモデルまたはクエリの問題が半日から1日解決する場合があるため、JPAの生産性は不正です。設定と呼び出しの組み合わせを使用して、正しくてパフォーマンスの高いものを生成します。

SQLを自分で作成したので、Ibatisにはこの種の問題はありません。 PL/SQL Developer、SQL Server Management Studio、Navicat for MySQLなどでSQLを実行してテストします。クエリが正しくなった後は、入力と出力をマッピングするだけです。

また、JPA-QLは純粋なSQLよりも扱いにくいことがわかりました。 JPA-QLクエリを実行して結果を確認するには、別のツールが必要です。さらに学習する必要があります。一部の人々はそれを愛していますが、私は実際にJPAのこの部分全体がかなりぎこちなく扱いにくいと感じました。

保守性/安定性

ここでのIbatisの危険性は急増です。つまり、開発チームは再利用を探すのではなく、必要に応じて値オブジェクトとクエリを追加し続けるだけですが、JPAにはテーブルごとに1つのエンティティがあり、エンティティが存在すればそれだけです。名前付きクエリはそのエンティティに適用される傾向があるため、見落とすことはありません。アドホッククエリは引き続き繰り返すことができますが、潜在的な問題は少ないと思います。

ただし、剛性は犠牲になります。多くの場合、アプリケーションでは、さまざまなテーブルからのビットやデータが必要になります。 SQLを使用すると、単一のクエリ(または少数のクエリ)を記述してすべてのデータを1回のヒットで取得し、その目的のためだけにカスタム値オブジェクトに配置できるため、簡単です。

JPAを使用すると、そのロジックをビジネスレイヤーに移動できます。エンティティは基本的に全部かゼロかです。しかし、それは厳密には当てはまりません。さまざまなJPAプロバイダーを使用すると、エンティティなどを部分的にロードできますが、それでも同じ個別のエンティティについて話していることになります。 4つのテーブルのデータが必要な場合は、4つのエンティティが必要であるか、必要なデータをビジネスレイヤーまたはプレゼンテーションレイヤーのある種のカスタム値オブジェクトに結合する必要があります。

Ibatisについて私が気に入っているもう1つの点は、すべてのSQLが外部(XMLファイル内)であることです。一部の人はこれが不利であることを指摘しますが、私ではありません。その後、XMLファイルを検索することで、テーブルや列の使用法を比較的簡単に見つけることができます。コードにSQLが埋め込まれている場合(またはSQLがまったくない場合)は、見つけるのが非常に難しくなる可能性があります。 SQLをデータベースツールにカットアンドペーストして実行することもできます。これが何年にもわたって私に役立った回数を十分に誇張することはできません。

パフォーマンス/スケーラビリティ

ここで私はibatisが勝つと思います。それは単純なSQLであり、低コストです。その性質上、JPAは同じレベルのレイテンシまたはスループットを管理することはできません。 JPAの目的は、レイテンシとスループットが問題になることはほとんどないということです。ただし、高性能システムは存在し、JPAのようなヘビー級のソリューションを嫌う傾向があります。

さらに、ibatisを使用すると、必要な列と正確に一致する必要なデータを返すクエリを作成できます。基本的に、JPAが個別のエンティティを返すときに、JPAがこれに勝る(または一致する)方法はありません。

トラブルシューティングのしやすさ

これもイバティスの勝利だと思う。上で述べたように、JPAでは、エンティティマネージャーが管理対象外のオブジェクト(バッチの一部である可能性がある)を永続化しようとしたために、クエリまたはエンティティが必要なSQLを生成したり、トランザクションが失敗する問題を診断したりするのに、半日かかる場合があります。あなたが多くの仕事をしたので、見つけるのは簡単ではないかもしれません。

存在しないテーブルまたは列を使用しようとすると、どちらも失敗します。これは良いことです。

その他の基準

ここで、移植性を要件の1つとして言及しませんでした(データベースベンダー間を移動することを意味します)。ここでJPAが有利であることは注目に値します。注釈は、たとえばHibernate XMLよりも移植性が低い(たとえば、標準のJPA注釈にはHibernateの「ネイティブ」IDタイプに相当するものがない)が、どちらもibatis/SQLよりも移植性が高い。

また、移植可能なDDLの形式としてJPA/Hibernateが使用されることも確認しました。つまり、JPA構成からデータベーススキーマを作成する小さなJavaプログラムを実行します。ibatisでは、次のスクリプトが必要です。サポートされている各データベース。

移植性の欠点は、JPAが、ある意味で最も低い共通点であることです。つまり、サポートされている動作は、主に幅広いデータベースベンダーで共通にサポートされている動作です。 ibatisでOracle Analyticsを使用する場合は、問題ありません。 JPAで?まあ、それは問題です。

112
cletus

IBatisとHibernateの間の単純な経験則は、世界のより多くのSQL /リレーショナルビューが必要な場合、iBatisの方が適しているということです。また、より複雑な継承チェーンと、SQLへの直接的なビューが少ない場合は、Hibernateを使用します。どちらも広く使用されている優れたフレームワークです。したがって、どちらもおそらくうまくいくと思います。おそらく両方のチュートリアルを読んで、一方が他方よりも優れているかどうかを確認して、どちらかを選択してください。

あなたが挙げるもののうち、私はパフォーマンスがそれほど異なるとは思いません-ボトルネックはほとんど常にデータベースであり、フレームワークではありません。その他については、さまざまな開発者がどちらかを好むと思います。つまり、一般に受け入れられている優先順位はありません(iBatisとHibernateの場合)。

11
StaxMan

どちらのソリューションを使用するかは、Java EE仕様に準拠するために選択した(または必要な)コンプライアンスに依存します。JPAは、Java EEシステムなので、これに固執することにこだわる場合は、それを使用する必要があります(いくつかの注意事項があります)。

JPAは、オブジェクトリレーショナルマッピングシステムの標準化です。そのため、実装は提供されず、標準化されたアプローチが定義されるだけです。 Hibernate Entity Managerは、そのような実装の1つです。

JPAは複数のベンダーにまたがる標準であり、それでもまだかなり新しいため、いくつかのユースケース(たとえば、動的SQLを生成するためのCriteria API)で価値のある難解な機能が不足しています。 Hibernateを直接使用したり、JDBCを直接使用したりする必要がある状況でJPAプランを使用する場合。このような状況では、一般的なDAOパターンが非常に役立ちます。あなたはこれを変更することができます: Generic Data Access Objects JPA&JDBCで使用するために非常に簡単です。

JPAにはいくつかの難しい制限があり(特にHibernateに慣れている場合)、まっすぐなJDBCの作成に慣れている開発者には難しい特定のアプローチが課されます。これをアプローチとして支持している場合は、ORMとJDBCの賛否両論について必ず宿題を立ててください。

JPAを使用する場合、学習曲線に到達すると、単純な開発(特に上記のDAOパターンを適切に実装した場合)だけでなく、クエリ結果の多層キャッシュを取得するという点でも効果があります。適切に実行された場合(大きな "if"であることがわかります)、これがハンサムな利点を提供することを確認しました。

最後に、柔軟性がほとんどないレガシーデータモデルを使用している場合、Hibernate(およびJPA)は、おそらく価値があるよりも多くの問題をもたらします。例えば:

  • データベースに主キーの候補がない場合(効果的なhashCode&equals実装の場合)、どの列が行を一意に定義しているかを事前に分析する必要があります-スキーマの複雑さによっては単純かもしれませんが、複雑かもしれません。
  • バージョン列またはタイムスタンプ列を追加できない場合、Hibernateが楽観的ロックを実行する機能が失われ、更新前にクエリを実行する必要があります。

(最初のコメントに応じて追加されます)データベースを再設計できるほど幸運である場合、次の2つの非常に重要な考慮事項ORMを使用する:

  • 楽観的ロックをサポートするために、関連するすべてのテーブルにバージョン番号列を追加します。
  • データ分析中に、開発者がhashCode()equals()に使用する必要があるnull不可の " alternate key "列を決定します。これらのメソッドではPK列を使用しないでください。
7

リストに別のオプションを追加するには...見てください:

Ebean ORM( http://ebean-orm.github.io )。

主な主張は、JPAやHibernateよりもシンプルで直感的なプログラミングモデルです。具体的には、HibernateセッションまたはJPA EntityManagerがなく、デタッチ/アタッチされたオブジェクト(マージ、永続化、フラッシュなし)がなく、遅延ロードが機能します。

...別名、使用と理解がはるかに簡単です。

独自のSQLをEbean(クエリ、更新、ストアドプロシージャ用)で使用することもできます。IMOは、独自のSQLを使用して、使いやすさの点でIbatisと一致します。

ORMをJava SEで使用することを検討している場合は、チェックすることをお勧めします。

  • LGPLライセンス
  • マッピングにJPAアノテーションを使用(@ Entity、@ OneToManyなど)
  • セッションレスAPI(代わりにマージ、永続化、フラッシュ... save()およびdelete()なし)
  • 「部分オブジェクト」のサポート
  • 大規模なクエリのサポート(オブジェクトグラフの永続コンテキストごと)
  • バックグラウンドクエリ
  • バッチ処理の優れたサポート
  • 自動クエリ調整( "Autofetch"による)

乾杯、ロブ。

6
Rob Bygrave

現在、Hibernateとibatisの両方を使用するプロジェクトに取り組んでいます。なぜ休止状態を使用するのですか?ドメインモデル、関係、継承をサポートします。かなり複雑なドメインモデルがあり、Hiberanteはそれを非常によくサポートしています。挿入、更新などを書くことを心配する必要はありません。Ibatisはビューにのみ使用されます。クエリがあり、クエリでマップされたビューオブジェクト(ドメインモデルではなくドメインモデルと同様)があります。 Ibatisは、Spring JDBCで管理する必要がある結果セットからの読み取りについて心配することなく、必要なビューオブジェクトのデータを返します。 HQlやSpring JDBCを使用する代わりに、なぜそれを行うのですか?ドメインは非常に複雑で、ビューをレンダリングするときに、ネイティブSQL関数の計算、グループ化、およびトンを実行します。これらすべてをクエリで実行し、動的クエリを使用して、ibatisで条件を管理し、クリーンで軽量なオブジェクトを取得します。休止状態でデータをフェッチするために複数のレイヤーを下に移動する必要がある場合は、はるかに意味があります。状況に応じて、どちらか一方だけを使用するか、両方を使用するか、まったく使用しない場合があります。しかし、間違いなく、休止状態はなくてはならないものではありません。

5
vsingh

重要なマルチスレッドアプリケーションでJPA/Hibernate(およびおそらく他のほとんどのORMソリューション)を使用すると、データベースセッションを厳密に1つのスレッドに限定する必要があるため(Sessionオブジェクトはスレッドセーフではないため)、すぐに本物のPITAになる可能性があることに注意してください。レイジーローディングを追加し、永続エンティティが最大で1つのアクティブなセッションに属することができるという事実を追加します...

* multi-threaded * SwingアプリケーションでHibernateを使用したセッション管理 を確認することをお勧めします(または単に 'hibernate multi-threaded'を検索してください)。

私の経験則(YMMV):アプリケーションが(Webサービスなどの)ある種の要求/応答サイクルに向いていない場合は、おそらく他のものを使用した方がよいでしょう。

もちろん、別のソリューションは、前述のフレームワークの制限を回避する方法でアプリケーションを設計することです。フレームワークXYZが機能するようにアプリケーションのデザインを変更すると、後味が悪くなります。

とにかく、たったの$ 0.02

4
JavaGuy

Java(またはOO)を使用する主な理由を考慮する必要があると思います。

システムは柔軟で、仕様を常に変更できる必要があります(これは実際に頻繁に発生します)。それ以外の場合は、はるかに高速であるため、Cでプログラミングする必要があります。

Webアプリケーションに最適なスタックはJava EE:JPA-EJB-JSF(スコープの拡張された永続化コンテキストを使用))だと思います。

JSFは、純粋なJSP /サーブレットよりも低速ですが、開発は高速です。

JPAは習得が困難ですが、開発は速く(ご存知のとおり、RAD)、変更による大きな(エラーが発生しやすいコピーと貼り付け)影響はありません。最も使用されているエンティティに新しい列を追加すると、iBatisのすべてのステートメントを更新する必要があります...

JPAはすべてのケースで十分に機能するわけではありませんが、ほとんどのケースをカバーし、コードを変更せずにJPQLの代わりにネイティブクエリをプラグインすることもできます。しかし、あまりにも多くのネイティブクエリを作成していることに気付いた場合、プロジェクトのiBatisに適合する可能性があります。

また、パフォーマンスに関しては、SQLへの変換方法を理解している場合、そして彼が得意なことを行うためにそれを置く場合、JPAは彼にとって不快な何かをするために置く場合、それはまた高性能です。生成されるクエリが多すぎます。魔法はありません!生成されたクエリに注意する必要があります。複雑なケースが発生する可能性がある場合に、簡単な方法をとることを盲目的に望んではなりません。

また、開発者がSQLのすべての機能を持っている場合、一元化された場所に置くのではなく、複雑すぎるクエリを記述してビジネスロジックを処理するのではなく、SQLやEJBにビジネスロジックが含まれます。 JPAはビジネスロジックではなく、モデルを永続化するためのものです。

基準クエリは、安全なnomatterhowcomplex動的クエリを構築するためにも適合しません。

4
Cosmin Cosmin

実際にグリーンフィールドプロジェクトがある場合は、休止状態を使用できますが、学習曲線は非常に急勾配であることに注意してください。

既存のデータベースがある場合、iBatisの方がはるかに優れています。1日後には生産性が向上し、さらに2日後にはすべてについて知ることができるからです。

考慮しなければならないことの1つは、休止状態の条件APIがカスタムクエリの作成に優れていることです。これは、アプリケーションによっては適切な引数となる場合があります。

3
Mauli

JPAを使用することをお勧めします。また、プロジェクトの期間/スコープに(大きく依存して)JPA2を検討することをお勧めします。JPAには欠けている機能の一部(たとえば、非常に優れたクエリAPI)があるためです。

2
Joachim Sauer

優れたオブジェクトモデルがない場合、Hibernateの利点はわかりません。リレーショナルデータベースがあるので、ORMには確かに「リレーショナル」がありますが、「オブジェクト」が重要です。オブジェクトなし、ORMなし。オブジェクトとテーブルを1対1でマッピングしても、より豊かなオブジェクトの動作がなければ、ORMは正当化されません。それがあなたの状況であるならば、JDBCまたはiBatisに固執してください。

2
duffymo

休止状態で移動します。プロジェクトは間違いなく後で大きくなり、投資(休止状態の学習への投資)は何らかの形で報われます。

1
cherouvim