[解決済み] Spring DAOとSpring ORMとSpring JDBCの比較
質問
Springがサポートするデータアクセス技術について調べていたところ、複数の選択肢に言及していることに気づきましたが、それぞれの違いがよくわかりません。
- Spring-DAO ( http://docs.spring.io/spring/docs/2.0.8/reference/dao.html )
- スプリング-ORM ( http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/orm.html )
- Spring-JDBC ( http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/jdbc.html )
私が理解するところでは、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
がスローされることになります。
しかし、以下の理由により、この方法は限定的であることに注意してください。
- プロバイダがトランザクションをロールバックした可能性があるため (正確な例外のサブタイプに依存)、通常は永続化例外をキャッチすべきではありません。
-
例外の階層は通常、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技術)用のモジュールも提供しています。
今後の展開
これらのことが分かったら、次は何を選ぶかを決めなければなりません。ここで良いニュースは、技術に対して決定的な最終選択をする必要がないことです。開発者として、コードを書くときはビジネスに集中し、うまくやれば、基礎となる技術を変更することは、実装や設定の詳細に過ぎないからです。
- エンティティ用のPOJOクラス、およびエンティティの属性と他のエンティティとの関係を表すget/setメソッドでデータモデルを定義します。技術に基づいてエンティティクラスとフィールドに注釈を付ける必要があるのは確かですが、今のところ、POJO で始めるには十分です。今はビジネス要件に集中してください。
- DAOのためのインターフェイスを定義します。1つのDAOは正確に1つのエンティティをカバーしますが、関係をナビゲートすることによって追加のエンティティをロードすることができるはずなので、それらの各々のためのDAOは確かに必要ないでしょう。厳密な命名規則に従って、ファインダーメソッドを定義してください。
- これに基づいて、他の誰かがあなたのDAOのモックを使って、サービスレイヤーに取り組み始めることができます。
- 様々な永続化技術(sql, no-sql)を学び、自分のニーズに最も合うものを見つけ、そのうちの一つを選びます。これに基づいて、エンティティにアノテーションを付け、DAOを実装します(spring-dataを選択した場合は、springに実装を任せます)。
- ビジネス要件が進化し、データアクセス技術が十分でない場合(例えば、JDBCといくつかのエンティティで始めたが、よりリッチなデータモデルが必要になり、JPAがより良い選択である場合)、DAOの実装を変更し、エンティティにいくつかのアノテーションを追加し、springの設定を変更( EntityManagerFactory定義の追加)しなければならなくなるでしょう。ビジネスコードの残りの部分は、あなたの変更から他の影響を受けることはありません。
参考:トランザクション管理
Springはトランザクション管理のためのAPIを提供しています。もしあなたがデータアクセスにspringを使うつもりなら、トランザクション管理にもspringを使うべきでしょう。Springがサポートする各データアクセス技術には、ローカルトランザクションに対応したトランザクションマネージャがあり、分散トランザクションが必要な場合はJTAを選択することができます。これらはすべて同じAPIを実装しているので、(もう一度言いますが)技術の選択は単なる設定の問題であり、ビジネスコードに影響を与えることなく変更することができるのです。
注:Springのドキュメント
あなたが言及したSpringのドキュメントへのリンクは、かなり古いものです。最新のリリース(4.1.6、すべてのトピックをカバー)のドキュメントを紹介します。
- 単一のhtmlページです。 http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/
- PDFです。 http://docs.spring.io/spring/docs/current/spring-framework-reference/pdf/spring-framework-reference.pdf
Spring-dataはSpringフレームワークの一部ではありません。原則に慣れるために最初に読むべき共通のモジュールがあります。ドキュメントはこちらでご覧になれます。
関連
-
[解決済み】Spring Data Maven Buildsの「プラグインの実行はライフサイクル構成でカバーされていません」を解決する方法
-
[解決済み] Spring Data JPAにおけるCrudRepositoryとJpaRepositoryのインターフェースの違いは何ですか?
-
[解決済み] Springのセキュリティ認証の例外を@ExceptionHandlerで処理する
-
[解決済み] Spring Hibernate - 現在のスレッドでトランザクションに同期したセッションを取得できませんでした。
-
[解決済み] Spring Boot Rest Controllerは、異なるHTTPステータスコードを返すには?
-
[解決済み] Spring Boot JPA - 自動再接続の設定
-
[解決済み] Spring BeanPostProcessorは具体的にどのように動作するのですか?
-
[解決済み] SpringでLocalDateTime RequestParamを使用するには?StringからLocalDateTimeへの変換に失敗しました」と表示される。
-
[解決済み] Spring: 静的フィールドに値を注入するには?
-
[解決済み] Spring Securityをセッションなしで使用するにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Springのセキュリティ認証の例外を@ExceptionHandlerで処理する
-
[解決済み] Spring Data JPAでネイティブクエリ結果をNon-Entity POJOにマップする。
-
[解決済み] Spring Hibernate - 現在のスレッドでトランザクションに同期したセッションを取得できませんでした。
-
[解決済み] Spring @PostConstruct と init-method 属性の比較
-
[解決済み] Spring Dataです。"delete by "はサポートされていますか?
-
[解決済み] Spring Boot JPA - 自動再接続の設定
-
[解決済み] Maven依存性 spring-webとspring-webmvcの比較
-
[解決済み] 同じurlパターンに対して異なる引数で2つのメソッドを作成する
-
[解決済み] Spring BeanPostProcessorは具体的にどのように動作するのですか?
-
[解決済み] SpringでLocalDateTime RequestParamを使用するには?StringからLocalDateTimeへの変換に失敗しました」と表示される。