Scalaのような関数型言語でORMが必要ないのはなぜですか?


30

Spring + HibernateプロジェクトでJavaからScalaに切り替えて、パターンマッチング、OptionなどのScalaの機能を活用し、一般的にはより簡潔な構文に見えるかどうか疑問に思っています。私はScalaエコシステムでデフォルトでORMを探していましたが、Activateのような考え方を見つけました(しかし、ほとんどはHibernateをScalaで使用できるかどうかを見つけようとしています)。これを検索して、JPA + Scalaに関するPlayのドキュメントでこれを読みました。

しかし、最も重要なポイントは、関数型言語の力を持っているときに、オブジェクトとリレーショナルのマッパーが本当に必要なのかということです。 おそらくない。JPAは、データ変換におけるJavaのパワー不足を抽象化する便利な方法ですが、ScalaからJavaを使用し始めると、本当に間違っていると感じます。

私は関数型プログラミングを使用して完全なアプリケーションを作成する方法を深く理解していません(だからこそ、オブジェクト指向と関数型を組み合わせているため、これを段階的に理解できるようにScalaを使用するつもりです)。関数型言語のORMが必要ない理由と、ドメインモデルの永続性に取り組むための関数型アプローチはどうなるのか。

Scalaでは、ビジネスロジックに対するDDDアプローチが依然として理にかなっていますよね?


3
これは意見に基づく質問です。Scalaは純粋に機能的ではなく、OO言語でもあるため、なぜORMツールを使用したいのかを説明できます。DBマッピングについては、例:SlickSORMAnormを参照してください。
ジェスパー

私は意見を探しているのではなく、永続性を達成する方法とは何かという機能的パラダイムを深く理解したものを求めています。Scalaはハイブリッドであることを知っており、そのOO部分をDDDに使用したいと思います。だから、ScalaでさえDDDアプローチをとるなら、ORMが道だと言いますか?
-gabrielgiussi

関数型言語では、主にオブジェクトのようにアイデンティティを持たない値を扱います。したがって、ORMの主要な仕事の1つである変更追跡は必要ありません。
リー

2
あなたはこの講演が好きかもしれません:機能的から反応的-ドメインモデリングのパターン
ジェスパー

5
あなたはしないでください必要でORM 任意の主要な言語を。
GrandmasterB

回答:


30

さて、このような議論があるときは常に、オブジェクトリレーショナルマッパー( "ORM")とデータベース抽象化レイヤーを明確に区別することが重要です。ORMは一種のデータベース抽象化レイヤーですが、すべてのデータベース抽象化レイヤーがORMであるとは限りません。これを把握するための研究に一つの良いツールは、Pythonの人気があるSQLAlchemyのの「SQLツールキットとして法案自体をライブラリ、およびこれらは異なるものであるという考えを持つオブジェクトリレーショナルマッパー」(私の太字)、。彼らが主要な機能のページに置いたように:

ORMは不要

SQLAlchemyは、CoreORMとして知られる2つの異なるコンポーネントで構成されています。コア自体は完全な機能を備えたSQL抽象化ツールキットであり、さまざまなDBAPIの実装と動作に対する抽象化のスムーズなレイヤーを提供します。また、生成Python表現によるSQL言語の表現を可能にするSQL Expression Languageも提供します。既存のスキーマをイントロスペクトするだけでなく、DDLステートメントを発行できるスキーマ表現システム、およびPythonタイプからデータベースタイプへのマッピングを可能にするタイプシステムは、システムを完成させます。オブジェクトリレーショナルマッパーは、コア上に構築されるオプションパッケージです。

フロントページでは、ORMについて次のように説明しています。

SQLAlchemyは、オブジェクトリレーショナルマッパー(ORM)で最も有名です。これは、データマッパーパターンを提供するオプションのコンポーネントです。クラスを自由にデータベースにマッピングすることができ、さまざまな方法でオブジェクトモデルとデータベーススキーマを開発できます。最初からきれいに切り離された方法。

ORMの重要な考え方は、有名なオブジェクトリレーショナルインピーダンスの不一致を埋めることです。これは、ユーザー定義クラスとデータベーススキーマのテーブルとの関係を定義し、アプリケーションのクラスに自動「保存」および「ロード」操作を提供することを意味します。

対照的に、非ORMデータベース抽象化レイヤーは、オブジェクト指向ではなく、リレーショナルデータモデルとSQLによりコミットする傾向があります。そのため、テーブルとクラス間の「マッピング」を特徴とし、データベーススキーマをプログラマから隠すのではなく、データベースをプログラマに公開する傾向がありますが、APIと抽象化は優れています。たとえば、SQLクエリビルダーを使用すると、次のように、文字列を操作せずにプログラムで複雑なSQLクエリを生成できます(JavaのjOOQライブラリの例)。

// Typesafely execute the SQL statement directly with jOOQ
Result<Record3<String, String, String>> result =
    create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
          .from(BOOK)
          .join(AUTHOR)
          .on(BOOK.AUTHOR_ID.equal(AUTHOR.ID))
          .where(BOOK.PUBLISHED_IN.equal(1948))
          .fetch();

さて、Playフレームワークは私が今説明したものと100%一致しているようには見えませんが、彼らの議論はこの一般的な空間にあるようです。

jOOQライブラリーは、ORMのカウンターポイントとして検討する価値があります。また、読む価値のある関連ブログエントリもあります。


19

多くの関数型プログラミングを行うまで説明するのは難しいです。オブジェクト指向プログラミングでは、データは一種のオブジェクトにとどまり、そこにとどまります。そのオブジェクトは少し渡され、かなり修正されますが、通常、そのデータの存続期間中、基本的に同じ「アイデンティティ」で作業しています。

ORMは通常、そのパラダイムに基づいて設計されています。データベースからいくつかのデータを取得し、オブジェクトに変更し、潜在的にそれを大量に変更します。完了しても、データベースに書き戻すことができる同じオブジェクトが残っています。

関数型プログラミングの動作は異なります。データは、その存続期間にわたって単一のIDを保持しません。分割、コピー、共有、変換されます。一連の関数を介してフローし、最終的に必要な出力フォームに再アセンブルされます。データベースAPIが関数型言語で自然に感じるには、それを考慮する必要がありますが、JPAは考慮しません。


1
+1000 ScalaをJava ++であるかのように使用することを主張する人々は、言語の将来を恐れさせます:(
Andres F.

9

scalaでは、データベーステーブルをオブジェクトにマップすることは依然として有用であり、その方法はいくつかあります。

Scalaの世界で人気のあるフレームワークの1つは滑らかです。ORMではありません。これは、ORMではないためです(つまり、明示的に結合するように指示されない限り、関係を取得しません)。

したがって、オブジェクトをデータベース行にマップしますが、オブジェクトは不変であり(したがって、状態フラッシュはありません)、モナドDSLを使用してクエリを明示的に実行します。その結果、可変性に関する問題や予測不可能なN + 1の問題なしに、ORMの多くの「良い」部分が得られます。

アノームやストレートJDBC などのより薄いライブラリを使用し、機能的な手法を使用してコードを美しく保つことで、人々は大成功を収めていることに注意してください。

JDBCの上に機能的な手法を適用する素晴らしいライブラリーの1つがdoobieです。

したがって、データベースアクセスには多くの選択肢がありますが、Hibernate(事実上のORMのようです)は、可変性に偏っているため、最適なものの1つではありません。


0

オブジェクト指向言語でもORMは必要ありません。

最初に、永続ストレージからオブジェクトにデータを物理的にコピーする必要があると誰が言ったでしょうか?Smalltalkの背後にいるAlan Kayは、オブジェクトにデータを削除することを望んでいました。彼は、オブジェクトはそのデータが保存されているある領域への参照のみを持つことができると提案しました。

第二に、それを達成する最良の方法は何ですか?私はあなたのオブジェクトをその責任によって特定することをお勧めします。彼らが所有するデータについて考えることはありません。CRCカードのアプローチについて聞いたことがあれば、まさにそのために使用されます。

そして、最後に、万が一OOオブジェクトに戻った場合に備えて、これを実装する方法を紹介します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.