JPAとSpringJdbcTemplate [クローズ]


84

新しいプロジェクトの場合、JPAは常にリレーショナルデータを処理するための推奨ツールですか、それともSpring JdbcTemplateがより良い選択であるシナリオはありますか?回答で考慮すべきいくつかの要因:

  • 新しいデータベーススキーマと既存のスキーマおよびテーブル
  • 開発者の専門知識のレベル
  • データキャッシングレイヤーとの統合が容易
  • パフォーマンス
  • 考慮すべき他の関連要因はありますか?

2
考慮したいもう1つの要素は、標準化です。
Eldad Mor

回答:


144

ドメインモデルを介してデータベーススキーマにアクセスしたくない場合は、SpringJdbcTemplateを使用してください。JdbcTemplateを使用すると、より柔軟性のある低レベルのアクセスを使用しますが、おそらくより多くの定型文も使用します。

Spring JdbcTemplateは、エキゾチックなデータベーススキーマとストアドプロシージャフォーカスでより簡単に使用できます。JPAを使用して、データベーススキーマがドメインモデルに正しくマップされていることを確認する必要があります。

どちらのテクノロジーにも、リレーショナルデータベース、SQL、トランザクションを知っている開発者が必要です。ただし、JPAを使用すると、隠れた複雑さが増します。

私の知る限り、JPAは、オブジェクト指向のフォーカスによってキャッシュエントリの識別、更新、無効化が容易になるため、データキャッシュレイヤーに簡単にプラグインできます。

JdbcTemplateベースのバックエンドをより適切に微調整できますが、ほとんどの場合、より多くのコードが関係します。

考慮すべき他のいくつかの側面は、JPAを使用すると、データベーススキーマのドメインモデルを取得できますが、多くの場合、追加のDTOクラスを使用する必要があるということです。JdbcTemplateを使用すると、DTOクラスを直接操作できます。


4
リレーショナルデータベース、SQL、トランザクションを知る必要がある開発者についての+1の良い点。ただし、JPAを使用すると、永続層をテーブルとしてだけでなく、テーブルに基づくオブジェクトとして扱うことができます。
Michael Wiles 2011年

@Timo接続プールの観点からこれを理解しようとしています。では、JPAは接続プールを備えたHikarCPのようなデータソースを持つことができますか?または、JPAはそれを独自に処理しますか
Joey587 2018

76

この投稿には少し遅れていますが、ORMではなくJdbcTemplateを使用する傾向があります。私はSQLを(かなりよく)知っていて、DBから「抽象化」されたくありません。ほとんどの場合、私のアプリはDBビューを使用しており、ほとんどのビジネスロジックをプッシュアップしています。JdbcTemplateが実装されているDAOを適切に階層化しました。それは「クリーン」に感じられ、ほとんどの定型コードはJdbcTemplateによって隠されています(そして、オンラインドキュメントはORMのものよりもはるかに優れているようです)。Hibernateのようなものを使用した限られた時間は、それが機能するときに見つけたので、時間を節約できます...しかし、正しく機能しなかったときは、「WTF」デバッグに数日かかりました。JdbcTemplate DAOimplのデバッグに20分以上費やす必要はありませんでした。他の人が指摘しているように、重要なのはSQL /スキーマ設計にどれだけ慣れているかだと思います


48

@Timoに同意します。私が追加/拡張する他の唯一の洞察は、ORMがデータへの純粋なSQLアクセスとは異なるセマンティクスを持っているということです。

ORMのポイントは、データがDB内にあるという事実を可能な限り抽象化することです。ORMを適切に使用すると、すべての永続化操作が1つの(できれば)薄いレイヤーで処理されます。モデルオブジェクトには、永続性コードがほとんどまたはまったくありません。ORMを使用しているという事実は、モデルからは見えないはずです。

このため、ORMは、特定の種類の操作、つまり単純なCRUD操作であなたの生活を楽にするのに非常に優れています。モデルオブジェクトのロード、表示、更新、削除を非常に簡単に行うことができます。データにアクセスすると、ビジネスロジックを記述できるモデルオブジェクトが返されるため、作業が楽になります。JDBCを使用する場合は、データからオブジェクトインスタンスを「ハイドレイト」する必要があります。これは、複雑でエラーが発生しやすい場合があります。

ORMが常に最良の選択であるとは限りません。JPAは仕事のためのツールです。ツールが仕事に十分でない場合は、より良いツールを見つけたいと思うでしょう。たとえば、オブジェクトグラフ全体をコピーして、それらのオブジェクトの新しいコピーを保存する必要があるシナリオがありました。(私がやろうとしたように)ORMを使用した場合は、DBからすべてのオブジェクトをロードし、それらをコピーしてから、新しいオブジェクトを保存する必要がありました。時間がかかりすぎた。

より良い解決策は、単にjdbcベースの操作を使用し、「select経由で挿入」SQL呼び出しを使用して新しい行を作成することでした。それは速く、コードはより単純でした。

考慮すべきもう1つのことは、JDBCに慣れていて、期限があり、ORMの時流に乗る必要がないということです。Spring JdbcTemplateクラスは、非常に強力で便利です。時々、仕事に最適なツールはあなたが知っているものです。ORMに精通している必要がありますが、必ずしも期待の高いプロジェクトではありません。学ぶべきことがたくさんあり、それは些細なことではありません-実際には、jdbcとormを使用するという選択において、ある複雑さのセットを別のセットと交換しています。


9
終了ステートメントの+1。これは一般にjdbcとormの間の決定であり、JPAとJdbcTemplateに固有のものではありません。
パルベス2012

2
メモリーフットプリントはどうですか?JdbcTemplateとSpring-Data-Jpaの間に大きな違いはありますか?(休止状態で私は推測します)
かみそり

36

他の回答には記載されていませんが、両方を使用しても問題ありません。私のアプリでは、JPAとJdbcTemplateを使用しています。クラッドタイプの操作には、JPAを使用していますが、レポートや、より簡単な場合は、jdbcTemplateを使用しています。

@Repository
public class FooRepository
{
    @PersistenceContext
    private EntityManager entityManager;

    @Autowired(required = true)
    private JdbcTemplate jdbcTemplate;

    public void saveFoo(Foo foo)
    {
         this.entityManager.persist(foo);
    }

    public List<SomeReportPojo> getSomeReport()
    {
         return this.jdbcTemplate.queryForList("SELECT .. ",SomeProjectPojo.class); 
    }
}

Springの優れている点は、JPA例外からSpring Dao例外階層への例外変換が、JPAとjdbcTemplateの両方で機能することです。したがって、意味がある場合はJPAを使用し、意味がある場合はjdbcTemplateを使用します。


20
の行はgetSomeReport()this.jdbcTemplate. ...はなくする必要がありthis.entityManager. ...ますか?
Jan Zyka 2014

XMLを使用せず、アノテーションのみを使用する場合、JdbcTemplate Beanをどのように宣言しますか?Springによって自動的に実行されません:NoSuchBeanDefinitionExceptionが発生します:タイプ[org.springframework.jdbc.core.JdbcTemplate]の修飾Beanが見つかりません
xtian 2017年

5

仕事では、柔軟性が高いため、HibernateJDBCTemplateを使用します。また、アプリに不要なデータを大量に「ロード」しないため、JPAよりもパフォーマンスが向上します。
JDBCTemplateの場合、SQLスキルは、必要なものを適切な速度で正確に提供するのに大いに役立ちます。


1
こんにちは、「休止状態のjdbctemplate」を明確にしていただけますか?それはどういう意味ですか?HibernateとSpringJDBCTemplateの組み合わせ、または他の何か?
qizer 2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.