1. ホーム
  2. spring

[解決済み] Spring DAOとSpring ORMとSpring JDBCの比較

2022-11-22 10:02:35

質問

Springがサポートするデータアクセス技術について調べていたところ、複数の選択肢に言及していることに気づきましたが、それぞれの違いがよくわかりません。

私が理解するところでは、Spring JDBCはデータベースにアクセスするための定型的なコードを減らすためのテンプレートを提供します - あなた自身のSQLクエリを書いてください。

Spring-ORMは、HibernateやMy(i)BatisなどのORM技術を通じてデータベースにアクセスするための簡素化されたテンプレートを提供します。

SpringのウェブサイトによるSpring-DAOです。

Springのデータアクセスオブジェクト(DAO)サポートは、JDBC、Hibernate、JDOのようなデータアクセス技術と簡単に連携できるようにすることを目的としています。 JDBC、Hibernate、JDOのようなデータアクセス技術との連携が容易になることを目的としています。 のようなデータアクセス技術を簡単に扱えるようにすることです。

ORMとJDBCはDBにアクセスする方法が違うので、少しは理解できます。しかし、Spring-DAOはただただ混乱するばかりです!

これらの3つの違いは何なのか、どなたか明確にしていただけないでしょうか? どのシナリオでどれが優先されるべきでしょうか?

また、もうひとつのプロジェクトである Spring-DATA も利用可能です ( http://projects.spring.io/spring-data/ ) さて、これはSpringがサポートするすべてのデータアクセス技術の親プロジェクトといったところでしょうか、それともSpring-DAOの新しい名前というだけでしょうか?

どのように解決するのか?

それぞれの技術について紹介します。

Spring-DAO

Spring-DAOは厳密な意味でのSpringモジュールではなく、DAOを書くこと、そしてそれらをうまく書くことを指示するための規約です。そのため、データにアクセスするためのインターフェースや実装、テンプレートは提供しません。DAOを書くときは、アノテーションとして @Repository でアノテーションする必要があります。そうすれば、基礎となる技術 (JDBC、Hibernate、JPA など) にリンクされた例外は、一貫して適切な DataAccessException サブクラスに一貫して変換されます。

例として、現在Hibernateを使用していて、サービスレイヤーのcatchが HibernateException をキャッチし、それに反応するようにしたとします。JPAに変更しても、DAOのインターフェースは変更されず、サービス層はまだ HibernateException をキャッチするブロックがコンパイルされますが、DAOがJPAの PersistenceException . を使用することで @Repository を使うことで、基礎技術にリンクされた例外はSpringの DataAccessException に変換されます。サービスレイヤーがこれらの例外をキャッチし、もし永続化技術を変更することになれば、同じSpringの DataAccessExceptions がスローされることになります。

しかし、以下の理由により、この方法は限定的であることに注意してください。

  1. プロバイダがトランザクションをロールバックした可能性があるため (正確な例外のサブタイプに依存)、通常は永続化例外をキャッチすべきではありません。
  2. 例外の階層は通常、Springが提供するものよりもプロバイダで豊富であり、プロバイダ間の明確なマッピングはありません。これに依存するのは危険です。 しかしこれは、DAOにアノテーションを付けて @Repository でアノテーションするのは良いアイデアです。さらに、Springはアノテーションに他の便利な機能を追加するかもしれません。

Spring-JDBC

Spring-JDBCはjdbcTemplateクラスを提供します。このクラスは DataSource で設定するだけで、次のようなコードを書くことができます。

int nbRows = jdbcTemplate.queryForObject("select count(1) from person", Integer.class);

Person p = jdbcTemplate.queryForObject("select first, last from person where id=?", 
             rs -> new Person(rs.getString(1), rs.getString(2)), 
             134561351656L);

Spring-JDBCはjdbcdaoSupportも提供しており、これを拡張することでDAOを開発することができます。これは基本的に2つのプロパティ、DataSourceとjdbcTemplateを定義し、その両方を使用してDAOのメソッドを実装することができます。また、SQL例外からspring DataAccessExceptionsへの例外トランスレータも提供します。

プレーンなjdbcを使用する場合、このモジュールを使用する必要があります。

Spring-ORM

Spring-ORMは、JPA、JDO、Hibernate、iBatisという多くの永続化技術をカバーする包括的なモジュールです。これらの技術のそれぞれについて、Springの構成原則に従って各技術を利用できるように統合クラスを提供し、Springのトランザクション管理とスムーズに統合できるようにしています。

それぞれの技術について、基本的に構成は DataSource ビーンをある種の SessionFactory または EntityManagerFactory などのビーンです。純粋なJDBCの場合、JDBCはDataSourceにのみ依存するので、このような統合クラスは必要ありません(JdbcTemplateは別として)。

JPAやHibernateのようなORMを使用する予定がある場合、spring-jdbcは必要なく、このモジュールだけが必要です。

Spring-Data

Spring-Dataは、より汎用的な方法でデータにアクセスする方法(DAO + アノテーション)を定義するための共通のAPIを提供する包括的なプロジェクトで、SQLとNOSQLの両方のデータソースをカバーしています。

最初のアイデアは、開発者が技術にとらわれない方法でDAOのインタフェース(finderメソッド)とエンティティクラスを書き、設定のみ(DAOとampのアノテーション、エンティティ、xmlまたはJavaベースの春の設定)に基づいて、JPA(SQL)またはredis、hadoopなどの実装技術を決定する技術を提供することです。(NOSQL)です。

もしfinderメソッド名のためにspringによって定義された命名規則に従っていれば、最も単純なケースではfinderメソッドに対応するクエリ文字列を提供する必要さえありません。その他の状況では、finderメソッドのアノテーションの中でクエリ文字列を提供する必要があります。

アプリケーションコンテキストがロードされると、springはDAOインターフェースのプロキシを提供し、データアクセス技術に関連するすべての定型コードを含み、構成されたクエリを呼び出します。

Spring-Dataは非SQL技術に集中していますが、JPA(唯一のSQL技術)用のモジュールも提供しています。

今後の展開

これらのことが分かったら、次は何を選ぶかを決めなければなりません。ここで良いニュースは、技術に対して決定的な最終選択をする必要がないことです。開発者として、コードを書くときはビジネスに集中し、うまくやれば、基礎となる技術を変更することは、実装や設定の詳細に過ぎないからです。

  1. エンティティ用のPOJOクラス、およびエンティティの属性と他のエンティティとの関係を表すget/setメソッドでデータモデルを定義します。技術に基づいてエンティティクラスとフィールドに注釈を付ける必要があるのは確かですが、今のところ、POJO で始めるには十分です。今はビジネス要件に集中してください。
  2. DAOのためのインターフェイスを定義します。1つのDAOは正確に1つのエンティティをカバーしますが、関係をナビゲートすることによって追加のエンティティをロードすることができるはずなので、それらの各々のためのDAOは確かに必要ないでしょう。厳密な命名規則に従って、ファインダーメソッドを定義してください。
  3. これに基づいて、他の誰かがあなたのDAOのモックを使って、サービスレイヤーに取り組み始めることができます。
  4. 様々な永続化技術(sql, no-sql)を学び、自分のニーズに最も合うものを見つけ、そのうちの一つを選びます。これに基づいて、エンティティにアノテーションを付け、DAOを実装します(spring-dataを選択した場合は、springに実装を任せます)。
  5. ビジネス要件が進化し、データアクセス技術が十分でない場合(例えば、JDBCといくつかのエンティティで始めたが、よりリッチなデータモデルが必要になり、JPAがより良い選択である場合)、DAOの実装を変更し、エンティティにいくつかのアノテーションを追加し、springの設定を変更( EntityManagerFactory定義の追加)しなければならなくなるでしょう。ビジネスコードの残りの部分は、あなたの変更から他の影響を受けることはありません。

参考:トランザクション管理

Springはトランザクション管理のためのAPIを提供しています。もしあなたがデータアクセスにspringを使うつもりなら、トランザクション管理にもspringを使うべきでしょう。Springがサポートする各データアクセス技術には、ローカルトランザクションに対応したトランザクションマネージャがあり、分散トランザクションが必要な場合はJTAを選択することができます。これらはすべて同じAPIを実装しているので、(もう一度言いますが)技術の選択は単なる設定の問題であり、ビジネスコードに影響を与えることなく変更することができるのです。

注:Springのドキュメント

あなたが言及したSpringのドキュメントへのリンクは、かなり古いものです。最新のリリース(4.1.6、すべてのトピックをカバー)のドキュメントを紹介します。

Spring-dataはSpringフレームワークの一部ではありません。原則に慣れるために最初に読むべき共通のモジュールがあります。ドキュメントはこちらでご覧になれます。