21

DDD リポジトリ パターンについてはよくわかりませんが、Spring での実装は混乱を招きます。

public interface PersonRepository extends JpaRepository<Person, Long> { … }

インターフェイスは JpaRepository (または MongoDBRepository...) を拡張するため、あるデータベースから別のデータベースに変更する場合は、インターフェイスも変更する必要があります。

私にとって、インターフェースは抽象化を提供するためにありますが、ここではそれほど抽象的ではありません...

Spring-Data がそのように機能する理由を知っていますか?

4

3 に答える 3

11

そうです、インターフェイスは、外部の観点から、すべての実装クラスに対して同等に機能するものについての抽象化です。

そして、それはまさにここで起こることです:

  • JpaRepository はすべての JPA リポジトリ (すべての異なるエンティティ) の共通ビューですが、MongoDBRepository はすべての MongoDB エンティティで同じです。
  • しかし、JpaRepository と MongoDBRepository には、共通のスーパー インターフェイスで定義されているものを除いて、共通点はありません。

    • org.springframework.data.repository.PagingAndSortingRepository
    • org.springframework.data.repository.Repository

だから私には普通に見えます。

リポジトリを実装するクラスを使用する場合、JPA 実装からドキュメントベースの実装に切り替えることができるようにする場合は、PagingAndSortingRepository またはリポジトリを使用します (申し訳ありませんが、そのようなユースケースは想像できません - とにかく)。もちろん、リポジトリの実装は、それが何であるかに応じて、正しいインターフェース (JpaRepository、MongoDBRepository) を実装する必要があります。

于 2011-05-12T08:38:20.993 に答える
7

この背後にある理由は、このブログ投稿http://blog.springsource.com/2011/02/10/getting-started-with-spring-data-jpa/で明確に述べられています。

このインターフェースを定義することには 2 つの目的があります。まず、JpaRepository を拡張することで、アカウントの保存や削除などを可能にする汎用 CRUD メソッドの束を型に取得します。次に、これにより、Spring Data JPA リポジトリ インフラストラクチャがこのインターフェイスのクラスパスをスキャンし、Spring Bean を作成できるようになります。

ソースに非常に近いソースを信頼しない場合 (しゃれが意図されています)、この投稿も読むことをお勧めしますhttp://www.brucephillips.name/blog/index.cfm/2011/3/25/Using -Spring-Data-JPA-To-Reduced-Data-Access-Coding .

コーディングする必要がなかったのは、PersonRepository インターフェースの実装です。Spring はこのインターフェースの実装を作成し、PersonRepository Bean を Service クラスに自動配線できるようにします。PersonRepository Bean はすべての標準 CRUD メソッド (トランザクション対応) を持ち、Person オブジェクトまたは Person オブジェクトのコレクションを返します。そのため、Spring Data JPA を使用することで、独自の実装クラスを作成する手間を省きました。

于 2011-05-18T19:52:53.697 に答える
3

Spring Data の M2 までJpaRepositoryは、次の理由により、ユーザーに拡張を要求しました。

  1. クラスパス スキャン インフラストラクチャは、Spring Data JPA と Spring Data Mongo を並行して使用する可能性があるため、そのインターフェイスを拡張するインターフェイスのみを選択し、それらの両方がまったく同じパッケージを指しているため、どのストアに対してプロキシを作成するかが明確ではありません。Repositoryしかし、RC1 以来、それはかなり風変わりなケースであり、CrudRepositoryなどを使用するだけの利点は、前述のコーナー ケースで取らなければならない労力よりも重要であると考えているため、開発者にその負担を任せるだけです。exclude名前空間でand要素を使用includeして、これをより細かく制御できます。
  2. M2 までは、CRUD メソッドを再宣言して@Transactional. AnnotationTransactionAttributeSourceこの決定は、トランザクション構成を見つけるために使用するアルゴリズムによって決定されました。具体的なリポジトリ インターフェイスで CRUD メソッドを再宣言して適用するだけで、トランザクションを再構成する可能性をユーザーに提供したかったため@Transactionalです。RC1TransactionAttributeSourceでは、注釈をリポジトリの CRUD 実装に戻すことができるカスタムを実装することにしました。

簡単に言えば、要約すると次のようになります。

RC1 の時点で、必要な場合を除いて、ストア固有のリポジ​​トリ インターフェイスを拡張する必要はもうありません…</p>

  1. よりコアなリポジトリ インターフェースでは、ベースのアクセスの代わりにListベースのアクセスを使用します (ただし、共通の基本インターフェースで関連するメソッドを単純に再宣言して、同様に s を返すこともできます) 。findAll(…)IterableList
  2. などのJPA固有のメソッドを利用したいsaveAndFlush(…)

Repository一般に、RC1 以降の CRUD メソッドの公開に関しては、マーカー インターフェイスのみを拡張し、公開する CRUD メソッドを選択的に追加することさえできるため、はるかに柔軟です。バッキング実装は引き続きすべてのメソッドを実装するためPagingAndSortingRepository、呼び出しをインスタンスにルーティングできます。

public interface MyBaseRepository<T, ID extends Serializable> extends Repository<T, ID> {

  List<T> findAll();

  T findOne(ID id);
}

public interface UserRepository extends MyBaseRepository<User, Long> {

  List<T> findByUsername(String username);
}

その例では、and (CRUD メソッドを実装するインスタンスにルーティングされます) と、2 つの CRUD メソッドにファインダー メソッドを追加する具象リポジトリMyBaseRepositoryのみを公開するように定義します。findAll()findOne(…)

このトピックの詳細については、リファレンス ドキュメントを参照してください。

于 2011-07-06T05:52:21.147 に答える