私が開発したいくつかのアプリ(その後、忘れてしまった)については、主にMySQL用のプレーンなSQLを書いてきました。 SQLAlchemy のようにpythonでORMを使用しましたが、長い間それらに固執しませんでした。通常、それはドキュメンテーションまたは複雑さ(私の観点から)でした。
移植性のためにORMを使用します。1種類のデータベースを使用する場合はプレーンSQLを使用します。データベースのサポートが必要なアプリを開発するときに、ORMまたはSQLをいつ使用するかについてのアドバイスを本当に探しています。
それについて考えると、軽量のラッパーを使用してデータベースの不整合を処理する方が、ORMを使用するよりもはるかに良いでしょう。
ORMにはいくつかの素晴らしい機能があります。データベース列をオブジェクトフィールドにコピーするというわずらわしい作業の多くを処理できます。通常は、言語の日付と時刻のタイプを適切なデータベースタイプに変換します。通常、ネストされたオブジェクトをインスタンス化することにより、1対多の関係も非常にエレガントに処理されます。 ORMの長所と短所を念頭に置いてデータベースを設計すれば、データベースにデータを出し入れする手間が大幅に節約されます。 (それらをマッピングする必要がある場合、多態性と多対多の関係をどのように処理するかを知りたいでしょう。ORMを「コンピューターサイエンスのベトナム」と呼ぶ「インピーダンスミスマッチ」のほとんどを提供するのはこれら2つのドメインです。 )
トランザクション型のアプリケーションの場合、つまり、リクエストを行い、オブジェクトを取得し、それらをトラバースしてデータを取得し、Webページにレンダリングします。パフォーマンスへの負担は小さく、多くの場合、ORMはオブジェクトをキャッシュするため高速になります前に見たように、そうでなければ、データベースに複数回クエリを実行することになります。
レポートが多いアプリケーション、またはリクエストごとに多数のデータベース行を処理するアプリケーションの場合、ORMの税ははるかに重く、アプリケーションのキャッシュは大きな無駄なメモリ占有の負担になります。その場合、単純なSQLマッピング(LinQまたはiBatis)またはシンDALでの手作業でコーディングされたSQLクエリが最適です。
大規模なアプリケーションについては、両方のアプローチを使用していることに気付きます。 (簡単なCRUDの場合はORM、レポートの場合はSQL/thin DAL)。
Hibernate、EclipseLink、Toplink、OpenJPAなどを含むJPA(Java Persistence API、基本的にはJava/J2EE/EJB用の標準ORM API)でかなりの時間を費やした人として、私は私の一部を共有します観察。
もう少し説明が必要な別の問題があります。
Webアプリケーションの従来のモデルでは、永続化レイヤーとプレゼンテーションレイヤーを使用します(サービスまたは他のレイヤーが間にある場合がありますが、これらはこの説明の重要な2つです)。 ORMは、永続層からプレゼンテーション層(つまりエンティティ)までの固定ビューを強制します。
生のSQLメソッドの批判の1つは、単に1つのクエリで使用されるこれらすべてのVO(値オブジェクト)またはDTO(データ転送オブジェクト)になることです。これはORMの利点として宣伝されています。
つまり、これらの問題はORMで解消されるのではなく、単にプレゼンテーション層に移動するだけです。クエリ用のVO/DTOを作成する代わりに、通常はすべてのビューに1つずつ、カスタムプレゼンテーションオブジェクトを作成します。これはどうですか?私見ではありません。
これについて ORMまたはSQL:まだありますか? で書きました。
私が選択した永続化テクノロジー(Javaの場合)は最近、ibatisです。 JPAができることの90%以上を実行するSQLの非常に薄いラッパーです(十分に文書化されていませんが、関係の遅延ロードも実行できます)が、オーバーヘッドは(複雑さと実際のコードに関して)はるかに少ないです。
これは、昨年私が書いていたGWTアプリケーションで出てきました。 EclipseLinkからサービス実装のプレゼンテーションオブジェクトへの多くの翻訳。 ibatisを使用していた場合は、ibatisを使用して適切なオブジェクトを作成し、それらをスタックの上下に渡す方がはるかに簡単でした。一部の純粋主義者は、これがBad™であると主張するかもしれません。そうかもしれませんが(理論的には)、私はあなたに次のことを伝えます。それにより、コードが単純になり、スタックが単純になり、生産性が向上します。
ReadsのプレーンSQL、CUDのORMと言います。
パフォーマンスは、特にWebアプリケーションで常に懸念されるものですが、コードの保守性と可読性も重要です。これらの問題に対処するために、 SqlBuilder と書きました。
ORMは単なる移植性ではありません(ORMを使用しても実現するのは難しいです)。基本的に、永続的なストアを抽象化する層です。ORMツールを使用すると、定型的なSQLクエリ(PKまたは述語、挿入、更新、削除による選択)を記述せずに、問題の領域に集中できます。
インピーダンスの不整合を処理するためだけに、立派な設計ではデータベースを抽象化する必要があります。しかし、最も単純な最初のステップ(およびほとんどの場合に適切)は、ヘビーウェイトORMではなくDALになると予想しています。あなたの唯一のオプションは、スペクトルの終わりにあるものではありません。
DALとORMを区別する方法を説明するように要求するコメントに応じて編集します。
DALは、テーブルをカプセル化し、フィールドをプロパティにマップするクラスから始めて、自分で作成したものです。 ORMは、DBMSスキーマの他のプロパティ(主にPKおよびFK)から推測された、ユーザーが記述しないコードまたは抽象化メカニズムです。 (これは、自動抽象化が漏れ始めるかどうかを調べる場所です。意図的にそれらを通知することを好みますが、それは私の個人的な好みかもしれません)。
すべてのツールには目的とビジョンがあります。私は http://www.jooq.org/ を作成しましたが、iBatisはおそらくあなたにとっても良いソリューションではありますが、まさにあなたのニーズに合っています。
jOOQには基本的なORM機能がありますが、主に、ニーズに最適なORMを見つけようとするとき、ほとんどの開発者が最も必要とするものに焦点を当てています。
しかし、多くの場合、それらは行き過ぎて非常に多くの抽象化を提供するため、RDBMSに対して実行されているとは思わないでしょう。一方、RDBMSを選択した理由はまさに
jOOQはこれらのポイントに正確に対応します。 JDBCと同様に機能しますが、痛みはありません。
私のORMを本当に活用させた鍵は、コード生成でした。コードパフォーマンスの観点から、ORMルートは最速ではないことに同意します。しかし、中規模から大規模のチームがある場合、特にCIを使用している場合、ビルドプロセスの一部としてDBからクラスとマッピングを再生成する機能がDBによって急速に変化しているのは注目に値します。あなたのコードは最速ではないかもしれませんが、あなたのコーディングはそうなります-私はほとんどのプロジェクトでどちらを採用するか知っています。
私の推奨事項は、スキーマがまだ流動的である間にORMを使用して開発し、プロファイリングを使用してボトルネックを検出し、生のSQLを使用してそれを必要とする領域を調整することです。
別の考えとして、Hibernateに組み込まれたキャッシングは、適切な方法で使用すると、多くの場合、パフォーマンスが大幅に向上する可能性があります。参照データを読み取るためにDBに戻る必要はもうありません。
フレームワークを使用するかどうかのジレンマは、現代のソフトウェア開発シナリオでは非常に一般的です。
理解することが重要なのは、すべてのフレームワークまたはアプローチに長所と短所があることです-たとえば、経験上、ORMはトランザクション、つまり挿入/更新/削除操作を処理するときに便利ですが、複雑なデータをフェッチする場合はその結果、ORMツールのパフォーマンスと有効性を評価することが重要になります。
また、フレームワークまたはアプローチを選択し、その中のすべてを実装することは必須ではないことを理解することが重要です。つまり、ORMとネイティブクエリ言語を混在させることができます。多くのORMフレームワークは、ネイティブSQLのプラグインに拡張ポイントを提供します。フレームワークやアプローチを使いすぎないようにする必要があります。特定のフレームワークまたはアプローチを組み合わせて、適切なソリューションを提供できます。
ORMは、挿入、更新、削除、高レベルの同時実行によるバージョン管理に関して使用できます。また、レポート生成と長いリストにネイティブSQLを使用できます。
「1つのツールですべてに対応する」ソリューションはありません。これは、「or/mを使用するかどうか」という質問にも当てはまります。 '。
私は言うだろう:あなたが非常に他のロジックなしで非常に「データ」に焦点を合わせたアプリケーション/ツールを書く必要がある場合、SQLはこの種のアプリケーションのドメイン固有言語であるため、プレーンSQLを使用します。
一方、多くの「ドメイン」ロジックを含むビジネス/エンタープライズアプリケーションを作成する場合、このドメインをコードで表現できる豊富なクラスモデルを作成します。そのような場合、OR/Mマッパーは、多くの配管コードを手から取り出すので、そうするのに非常に役立ちます。
私はこの質問が非常に古いことを知っていますが、私のように誰かが出くわした場合に備えて答えを投稿すると思いました。 ORMは長い道のりを歩んできました。実際には、開発の生産性の向上とパフォーマンスの維持という両方の長所を備えています。
SQLデータをご覧ください( http://sqldata.codeplex.com )。すべてのベースをカバーするc#用の非常に軽量なORMです。
参考までに、私はSQL Dataの著者です。
機能するlikeSQLを使用しますが、コンパイル時のチェックと型の安全性を提供するORMを使用します。私のお気に入りのように: データ知識オブジェクト (開示:私はそれを書きました)
例えば:
for (Bug bug : Bug.ALL.limit(100)) {
int id = bug.getId();
String title = bug.getTitle();
System.out.println(id +" "+ title);
}
完全にストリーミング。セットアップが簡単です(定義するマッピングはありません-既存のスキーマを読み取ります)。結合、トランザクション、内部クエリ、集計などをサポートします。SQLでできることはほとんど何でも。そして、巨大なデータセット(金融時系列)から些細な(Android)までずっと証明されています。
私が開発したアプリの1つは、Pythonで作成されたIRCボットでした。使用するモジュールは個別のスレッドで実行されますが、sqliteを使用するときにスレッドを処理する方法がわかりません。ただし、別の質問の方が良いかもしれません。
タイトルand実際の質問の両方を書き直すべきでした。どの言語でも、以前にDALを実際に使用したことはありません。
「妥協点があります!」という返信のコーラスに私の声を加えたいと思います。
アプリケーションプログラマーにとって、SQLは、制御したいことと、制御に煩わされたくないことをほぼ確実に混在させたものです。
私が常に望んでいたのは、完全に予測可能な決定を担当するレイヤー(DAL、ORM、またはマイクロORMと呼びますが、どちらでもかまいません)(SQLキーワードの綴り方、括弧の位置、タイミング列エイリアス、2つのfloatとintを保持するクラス用に作成する列を作成するために...)、SQLの高レベルの側面、つまりJOINの配置方法、サーバー側の計算、 DISTINCT、GROUP BY、スカラーサブクエリなど。
だから私はこれを行う何かを書いた: http://quince-lib.com/
C++用です。それがあなたが使用している言語であるかどうかはわかりませんが、「中間」がどのように見えるかについてこれが見られるのはおもしろいかもしれません。