ORMは、コードのサイズを小さくするために、実際にはプリミティブプロジェクトでのみ必要であり、非常に大きく複雑なプロジェクトでは、ORMなしで行う方がよいことが示唆されました。 私は大規模なプロジェクトについて言います-他の人は小さなプロジェクトについて言いましょう:)私は、古典的な束であるJava / Oracleで議論と例を構築することを予約します。
ORMが必要な理由
マッピングのように、大規模プロジェクトではORM自体が非常に必要です。
想像してみてください-私には非常に大きなシステムがあり、その中に注文のテーブル、たとえば50列があります(実際、150がありますが、まあまあです。ノーマライザー、静かにしてください!通常の形式も知っています)。 そして今、あなたは1つの注文を選択して画面に表示することを想像する必要があります。 あなたが選択を書くと仮定すると、質問は-サーバーサイドJavaで、中間層でその結果をどうするかです。 たとえば、JSPページから直接ストアドプロシージャやリクエストを呼び出すことはありませんが(希望)、何らかのデータ構造の形でデータを取得して転送する必要があります。
それで、それらを配列、ArrayList-a、連想配列として[列名:値]として渡しますか? かさばり、不快で、間違いを犯しやすいです。 そして、複数の注文が必要な場合、結果を変換するためにネストされたコレクションを作成しますか? これは、その有害な効果において、すでによく知られているアンチパターン「文字列タイピング」に似ています。 Order型のオブジェクトのコレクションを使用できる場合は、ベクターのコレクションまたは連想配列を使用します。
ケースの例を見つけました。必要なすべてのプロパティを持つOrderオブジェクトが必要です。したがって、SQLクエリの結果をオブジェクト(そのようなオブジェクトのコレクション)に変換できるコードが必要です。
さらに、すべてのクエリを手で書くのは難しくて面倒で、間違いを犯しやすいのは明らかです。 Javaでは、文字列としてコードに表示され(静的な型付けとコンパイル時のチェックがないことを意味します)、Javaコードで保持する必要があります(小さい場合でもJavaコードがゴミになる)、または大きく、個別のXMLファイルにエクスポートします。
ここに若干の余談があります。 議論は、短いクエリのSQLコードをJavaコードで直接保持するのか、それとも長い間続けられているEnterprise-eの別のファイルにエクスポートするのかということです。
引数はJavaコード内から保持することです-一緒に使用されるコードは近くにあり、SQLクエリコードは、VCSの変更の場合に、1つのファイルのみを変更することを覚えておく必要があります2。
異なるクラスに分割するための引数は、複数行のSQLクエリがJavaコードをリターすることです(たとえば、Javaは同じGroovyとは異なり、複数行の文字列リテラルを完全にサポートしないため)+クラス定数として定義されている場合、コンテンツが変更されたときたとえば、この定数をjava hotswapにすると、失敗します。 私は通常、状況に応じて見てください:)
一般的に、大規模プロジェクトのORMは、ルーチンを簡素化するために必要です。 それなしではどこにもありません:)
純粋なSQLが必要な理由
もちろん、ORMのみを分配することはできません。 ORM / Javaを介して書かれた場合、10倍のスペースを占有し、2倍遅く動作するため(同時に、関係代数の観点からOOPの観点よりも簡単に記述されるようなロジックがあり、そのようなロジックはきしみを伴ってORMに基づいているためです) サブクエリ、ユニオン、トリッキーな結合を含む複雑なクエリも、純粋なORMを使用して記述するのは面倒です。 また、SQLオプティマイザー計画および統計/ DBMSレベルの監視ツール(Oracle、Explain Plan、tkprof、Grid Controlの場合)にアクセスせずに、少なくとも数億のレコードが使用されるテーブルで動作するクエリを最適化することは非常に困難です。 したがって、SQLなしでも-どこにもありません:)
それにもかかわらず、大規模なプロジェクトで純粋なSQLクエリを少しだけ甘くする方法について話すことができます。
1つのオプションは、マクロを使用することです。 SQLマクロを記述するための独自のフレームワークを作成します(本質的には、中程度に原始的なパーサーを実行するためのエンジンであり、ユーザーは独自のマクロとパーサーを作成できます)。 マクロは、次の問題の解決に役立ちます。
- クエリの再利用可能な部分(通常はサブクエリ)を別の、たとえば名前付きSQLコンポーネントに削除し、マクロを使用してクエリに含める
- SQL構文のいくつかの迷惑な違いを統合します。たとえば、クエリパラメーターがスカラー値である場合、または配列である場合、t.property = xとt.property in(x1、x2)の違いから抽象化するマクロを記述します。
- セキュリティ上の理由からwhere句に述語を追加する
- クエリ全体をSELECT * FROM(クエリ本体)tで...でラップして、統一された並べ替えとページングaをサポート
などなど。
異なるDBMS間の移植性について
はい、最後に。 ここでは、さまざまなDBMSとの互換性について一言も言いませんでした。 多くの場合、これは不要な要件です。 大規模で複雑なシステムは、DBMS固有の機能(SQL構文拡張機能、PL-SQL、T-SQL、pgplsqlなどの手続き型拡張機能の構文は一般に大きく異なり、パーティション構成など)を積極的に使用し、SQLコードを記述するための要件Oracle / MSSQL / DB2との互換性が同時にインストールされていないことがよくあります(ここでは、従来認識されているエンタープライズレベルのDBMSをリストしました。他のファンに腹を立てないでください)。 誰もが、これはシステムの大きな複雑化と感謝であり、常に正当化されるものではないことを理解しています。 OracleやIBMなどの真剣なベンダーからの真の独立は、非常に高価です。 しかし、どれくらいの頻度で本当に必要なのでしょうか?