web-dev-qa-db-ja.com

ORMを使用する利点は何ですか?

手書きのPHPサイトからフレームワークベースのサイトへの移行を検討しているWeb開発者として、あるORMが他のORMに勝る利点について多くの議論を見てきました。 一定の(?)サイズのプロジェクトであり、エンタープライズレベルのアプリケーションではさらに重要です。

開発者として何が得られますか?私のコードは、現在使用している個々のSELECTステートメントとどのように異なりますか? DBアクセスとセキュリティにどのように役立ちますか? DBスキーマとユーザー資格情報をどのように見つけますか?

編集:@ duffymoは私に明らかなはずだったことを指摘しました:ORMはOOPコードにのみ役立ちます。私のコードはオブジェクト指向ではないので、ORMが解決する問題に遭遇していません。

59
flamingLogos

オブジェクトを扱っていない場合は、ORMを使用してもほとんど意味がありません。

リレーショナルテーブル/列がオブジェクト/属性と1:1でマッピングされている場合、ORMを使用する意味はあまりありません。

オブジェクトが他のオブジェクトと1:1、1:m、またはm:nの関係を持たない場合、ORMを使用してもあまり意味がありません。

複雑で、手作業で調整されたSQLを使用している場合、ORMを使用する意味はあまりありません。

データベースのインターフェイスとしてストアドプロシージャを使用することに決めた場合、ORMを使用する意味はあまりありません。

リファクタリングできない複雑なレガシースキーマがある場合、ORMを使用してもあまり意味がありません。

これが逆です:

オブジェクト間の関係が1:1、1:m、およびm:nであるソリッドオブジェクトモデルがある場合、ストアドプロシージャはありません。また、ORMソリューションが提供する動的SQLのように、 ORMを使用します。

このような決定は常に選択です。選択、実装、測定、評価します。

86
duffymo

ORMは、データアクセスの問題の解決策であると宣伝されています。個人的には、エンタープライズプロジェクトでそれらを使用した後、それらはエンタープライズアプリケーション開発のソリューションではありません。たぶん、彼らは小さなプロジェクトで働いています。以下に、特にnHibernateで発生した問題を示します。

  1. 構成:ORMテクノロジでは、テーブルスキーマをオブジェクト構造にマップするための構成ファイルが必要です。大規模なエンタープライズシステムでは、構成が非常に急速に成長し、作成と管理が非常に困難になります。また、構成を維持することは、ビジネス要件とモデルがアジャイル環境で絶えず変化し進化するため、退屈で維持できなくなります。

  2. カスタムクエリ:定義済みのオブジェクトに適合しないカスタムクエリをマップする機能は、フレームワークプロバイダーによってサポートされていないか、推奨されていません。開発者は、アドホックオブジェクトとクエリを作成するか、カスタムコードを作成して必要なデータを取得することにより、回避策を見つける必要があります。単純なSelectよりも複雑な場合は、ストアドプロシージャを定期的に使用する必要があります。

  3. 所有権のバインド:これらのフレームワークでは、コンピューターサイエンス業界で標準化されていない独自のライブラリと独自のオブジェクトクエリ言語を使用する必要があります。これらの独自のライブラリとクエリ言語は、アプリケーションをプロバイダの特定の実装にバインドします。必要に応じて変更する柔軟性はほとんどまたはまったくなく、相互に連携する相互運用性もありません。

  4. オブジェクトクエリ言語:オブジェクトモデルでクエリを実行するために、オブジェクトクエリ言語と呼ばれる新しいクエリ言語が提供されています。データベースに対して自動的にSQLクエリを生成し、ユーザーはプロセスから抽象化されます。オブジェクト指向開発者にとって、これはSQLの記述の問題が解決されたと感じるため、利点のように思えるかもしれません。実用性の問題は、これらのクエリ言語が、ほとんどの現実世界のアプリケーションで必要とされる中級から上級のSQL構造の一部をサポートできないことです。また、必要に応じて開発者がSQLクエリを調整することを防ぎます。

  5. パフォーマンス:ORMレイヤーは、リフレクションとイントロスペクションを使用して、データベースからのデータでオブジェクトをインスタンス化し、設定します。これらは処理の観点からコストのかかる操作であり、マッピング操作のパフォーマンス低下につながります。最適化されていないクエリを生成するために変換されたオブジェクトクエリは、それらをチューニングするオプションがないため、パフォーマンスが大幅に低下し、データベース管理システムが過負荷になります。フレームワークは自動生成されるSQLの制御に関して柔軟性がほとんどないため、SQLのパフォーマンスチューニングはほとんど不可能です。

  6. 密結合:このアプローチは、モデルオブジェクトとデータベーススキーマの間に密接な依存関係を作成します。開発者は、データベースフィールドとクラスフィールドの間に1対1の相関関係を必要としません。データベーススキーマを変更すると、オブジェクトモデルとマッピング構成に波及効果があり、その逆も同様です。

  7. キャッシュ:このアプローチでは、オブジェクトの状態を維持および追跡し、キャッシュされたデータのデータベースラウンドトリップを削減するために必要なオブジェクトキャッシュとコンテキストの使用も必要です。これらのキャッシュは、多層実装で維持および同期化されていない場合、データの精度と同時実行性の点で大きな影響を与える可能性があります。多くの場合、この問題を解決するには、サードパーティのキャッシュまたは外部キャッシュをプラグインする必要があり、データアクセス層に大きな負担がかかります。

分析の詳細については、以下を参照してください。 http://www.orasissoftware.com/driver.aspx?topic=whitepaper

39
Ahmad

非常に高いレベル:ORMは、オブジェクトとリレーショナルのインピーダンスの不一致を減らすのに役立ちます。これらを使用すると、多くの解析/シリアル化を自分で行うことなく、完全なライブオブジェクトをリレーショナルデータベースから格納および取得できます。

開発者として何が得られますか?

まず第一に、それはあなたが乾いたままでいることを助けます。スキーマまたはモデルクラスのいずれかが信頼でき、もう一方が自動的に生成されるため、バグの数とボイラープレートコードの量が削減されます。

マーシャリングに役立ちます。 ORMは通常、個々の列の値を適切な型にマーシャリングするので、自分で解析/シリアル化する必要がありません。さらに、自分自身をラップする必要があるオブジェクトを単に行にするのではなく、DBから完全に形成されたオブジェクトを取得できます。

私のコードは、現在使用している個々のSELECTステートメントとどのように異なりますか?

クエリは行ではなくオブジェクトを返すため、新しいクエリを作成するのではなく、属性アクセスを使用して関連オブジェクトにアクセスできます。通常、必要なときにSQLを直接記述できますが、ほとんどの操作(CRUD)では、ORMは永続オブジェクトと対話するためのコードをより簡単にします。

DBアクセスとセキュリティにどのように役立ちますか?

一般的に、ORMにはクエリ(属性アクセスなど)を構築するための独自のAPIがあるため、SQLインジェクション攻撃に対して脆弱ではありません。ただし、生成されたクエリに独自のSQLを挿入できる場合が多いため、必要な場合に奇妙なことができます。このような挿入されたSQLには、自分自身をサニタイズする責任がありますが、そのような機能の使用を控える場合、ORMはユーザーデータを自動的にサニタイズする必要があります。

DBスキーマとユーザー資格情報をどのように見つけますか?

多くのORMには、スキーマを検査し、データベース内のオブジェクトと対話できるモデルクラスのセットを構築するツールが付属しています。 [データベース]ユーザー資格情報は通常、設定ファイルに保存されます。

33
Aaron Maenpaa

データアクセスレイヤーを手作業で記述する場合、基本的に独自の機能の乏しいORMを記述しています。

Oren Einiには、DAL/ORMに必要な基本機能と、時間をかけて独自の機能を作成することが悪いアイデアになる理由をまとめたNiceブログがあります。 http://ayende.com/Blog/archive/2006 /05/12/25ReasonsNotToWriteYourOwnObjectRelationalMapper.aspx

編集:OPは、彼のコードベースはあまりオブジェクト指向ではないと他の回答でコメントしています。オブジェクトマッピングの処理は、ORMの1つの側面にすぎません。 Active Record パターンは、オブジェクトがテーブルに1:1でマップされるシナリオでORMがどのように役立つかを示す良い例です。

14
Daniel Auger

主な利点:

  1. データベースの抽象化
  2. API中心のデザインメンタリティ
  3. 高レベル==基本レベルで心配する必要はありません(考えられていることです)

ORMとの連携は、データベース駆動型アプリケーションの進化であると言わざるを得ません。いつも書く定型的なSQLについて心配する必要はなく、インターフェースがどのように連携して非常に簡単なシステムを作ることができるかについても心配する必要はありません。

INNER JOINとSELECT COUNT(*)を心配する必要はありません。高レベルの抽象化で作業しているだけで、同時にデータベースの抽象化も行っています。

そうは言っても、実際には一度に複数のデータベースシステムで同じコードを実行する必要があるという問題に実際に遭遇したことはありません。ただし、ケースが存在しないというわけではなく、一部の開発者にとっては非常に現実的な問題です。

8
Derek P.

他のORMの代わりに、Hibernate(Javaの場合)だけを話すことはできません。

Hibernateは以下を提供します。

  • 実稼働システム上のテーブルのスキーマを実行時に自動的に更新します。いくつかのことを手動で更新する必要がある場合があります。
  • 孤立したデータを作成している不正なコードを記述できないようにする外部キーを自動的に作成します。
  • 接続プーリングを実装します。複数の接続プーリングプロバイダーが利用可能です。
  • 高速アクセスのためにデータをキャッシュします。複数のキャッシングプロバイダーが利用可能です。また、これにより、多くのサーバーをクラスター化して、スケーリングを支援できます。
  • データベースアクセスをより透過的にして、アプリケーションを別のデータベースに簡単に移植できるようにします。
  • クエリを記述しやすくします。通常「join」を3回記述する必要がある次のクエリは、次のように記述できます。
    • 「i.customer.address.city =?の請求書iから」これにより、特定の都市のすべての請求書が取得されます
    • invoiceオブジェクトのリストが返されます。その後、invoice.getCustomer()。getCompanyName();を呼び出すことができます。データがまだキャッシュにない場合、データベースはバックグラウンドで自動的に照会されます

データベースをリバースエンジニアリングしてhibernateスキーマを作成するか(自分で試したことがありません)、スキーマを最初から作成できます。

もちろん、新しい技術と同様に学習曲線はありますが、それだけの価値があると思います。

必要な場合は、最適化されたクエリを作成するために、さらに低いSQLレベルにドロップダウンできます。

8
Sarel Botha

使用されるほとんどのデータベースは、オブジェクトに直接変換されないリレーショナルデータベースです。オブジェクトリレーショナルマッパーが行うことは、データを取得し、更新、削除、挿入、および実行可能なその他の操作のためのユーティリティ関数を使用してその周りにシェルを作成することです。したがって、行の配列と考える代わりに、他の場合と同様に操作できるオブジェクトのリストがあり、完了したらobj.Save()を呼び出すだけです。

使用されているORMのいくつかを見てみることをお勧めします。私のお気に入りは、pythonフレームワーク、 Django で使用されるORMです。データベースでのデータの外観の定義を記述し、ORMが検証、チェック、およびデータが挿入される前に実行する必要のあるメカニズムを処理します。

6
Christian P.

個人的には、これまでORMテクノロジーを使用した経験はあまりありませんでした。私は現在、nHibernateを使用している会社で働いていますが、実際にはそれを実現できません。いつでもストアドプロシージャとDALをくれ!より多くのコードを確実に...しかし、デバッグが容易なより多くの制御とコード-nHibernateの初期バージョンを使用した私の経験から、それを追加する必要があります。

5
Peanut

ORMについて詳しく説明しているポッドキャストについては、次のリンクを参照してください。 http://se-radio.net/podcast/2008-12/episode-121-or-mappers-michael-ploed

4
Jared

開発者として何が得られますか?

Dbアクセス部分をコーディングする必要がないため、時間を節約できます。

私のコードは、現在使用している個々のSELECTステートメントとどのように異なりますか?

属性またはxmlファイルのいずれかを使用して、データベーステーブルへのクラスマッピングを定義します。

DBアクセスとセキュリティにどのように役立ちますか?

ほとんどのフレームワークは、パラメーター化されたSQLなど、該当する場合はdbベストプラクティスを順守しようとします。実装の詳細はフレームワークでコーディングされているため、心配する必要はありません。ただし、この理由から、使用しているフレームワークを理解し、予期しないホールを開く可能性のある設計上の欠陥やバグを認識することも重要です。

DBスキーマとユーザー資格情報をどのように見つけますか?

いつものように接続文字列を提供します。フレームワークプロバイダー(SQL、Oracle、MySQL固有のクラスなど)は、dbスキーマを照会し、クラスマッピングを処理し、必要に応じてdbアクセスコードをレンダリング/実行する実装を提供します。

4
Chris

ORMを使用すると、特定のSQLダイアレクトのコードから依存関係が削除されます。データベースと直接対話する代わりに、コードとデータベース実装の間の絶縁を提供する抽象化レイヤーと対話します。さらに、ORMは通常、パラメーター化されたクエリを構築することにより、SQLインジェクションからの保護を提供します。自分でこれを行うことができますが、フレームワークが保証されているのは素晴らしいことです。

ORMは、2つの方法のいずれかで機能します。既存のデータベースからスキーマを検出するものもあります(LINQToSQLデザイナーがこれを行います)。クラスにテーブルをマップする必要があるものもあります。どちらの場合も、スキーマがマップされると、ORMがデータベース構造を作成(再作成)できる場合があります。 DB権限はおそらく、手動またはカスタムSQLを使用して適用する必要があります。

通常、資格情報は、API経由で、または構成ファイルを使用してプログラムで提供されます-またはその両方、構成ファイルからのデフォルトですが、コードでオーバーライドできます。

4
tvanfosson

私は受け入れられた答えにほぼ完全に同意しますが、軽量の代替案を念頭に置いて修正できると思います。

  • 複雑な、手作業で調整されたSQLがある場合
  • オブジェクトが他のオブジェクトと1:1、1:m、またはm:nの関係を持たない場合
  • リファクタリングできない複雑なレガシースキーマがある場合

...次に、独自のデータベース統合を簡単に記述できる程度までSQLが隠されたり抽象化されたりしない軽量ORMの恩恵を受けることができます。

これらは、私の会社の開発者チームがJDBCの上に存在するために、より柔軟な抽象化を行う必要があると判断した多くの理由のうちのいくつかです。

同様のことを達成する多くのオープンソースの代替があり、 jORM が提案されたソリューションです。

軽量のORMを選択する前に、いくつかの最強の候補を評価することをお勧めします。これらは、抽象データベースへのアプローチがわずかに異なりますが、トップダウンビューからは類似しているように見える場合があります。

1
Martin

oRMフレームワークに関する私の懸念は、おそらく多くの開発者にとって魅力的なことです。

それは、DBレベルで何が起こっているのかを「気にする」必要性をなくすということです。アプリの日々の実行中に発生する問題のほとんどは、データベースの問題に関連しています。 100%ORMであり、データベースにヒットしているクエリをユーザーが知らない世界について少し心配します。

{これは逆の答えかもしれません:}}

0
phatmanace