2013-06-09 23 views
53

spring-dataとmongodbを使用して複雑なクエリを実行できるアプリケーションを作成する必要があります。私はMongoRepositoryを使って始めましたが、複雑なクエリで苦労して例を見つけたり、構文を実際に理解したりしました。Spring DataのMongoTemplateとMongoRepositoryの違いは何ですか?

私はこのようなクエリについて話している:

@Repository 
public interface UserRepositoryInterface extends MongoRepository<User, String> { 
    List<User> findByEmailOrLastName(String email, String lastName); 
} 

または私は構文権利を得ることはありませんので、私は試行錯誤してみましたJSONベースのクエリを使用します。 mongodbのドキュメントを読んだ後でさえ(構文が間違っているために動作していない例)。

@Repository 
public interface UserRepositoryInterface extends MongoRepository<User, String> { 
    @Query("'$or':[{'firstName':{'$regex':?0,'$options':'i'}},{'lastName':{'$regex':?0,'$options':'i'}}]") 
    List<User> findByEmailOrFirstnameOrLastnameLike(String searchText); 
} 

すべてのドキュメントを読ん後は、mongoTemplateがはるかに良い、その後MongoRepository文書化されているようです。私は、次のマニュアルを参照しています:

http://static.springsource.org/spring-data/data-mongodb/docs/current/reference/html/reference.html

あなたが使用する方が便利で強力な何であるかを教えてもらえますか? mongoTemplateまたはMongoRepository?どちらも成熟しているのですか?

答えて

95

"便利"と "使いやすい"という目標はある程度矛盾しています。リポジトリは、テンプレートよりもはるかに便利ですが、後者は、実行するものを細かく制御することができます。

複数のSpringデータモジュールでリポジトリプログラミングモデルが利用できるようになったため、SpringデータMongoDB reference docsの一般セクションで詳細なドキュメントを参照できます。

TLは、DR

は、我々は一般的に以下のアプローチをお勧めします:リポジトリ抽象と

  1. スタートし、ちょうどクエリ導出機構や、手動で定義されたクエリを使用して単純なクエリを宣言します。
  2. より複雑なクエリの場合は、手動で実装されたメソッドをリポジトリに追加します(ここで説明します)。実装にはMongoTemplateを使用してください。ご例えば

詳細

これは次のようになります。

  1. は、カスタムコード用のインターフェイスを定義します。

    interface CustomUserRepository { 
    
        List<User> yourCustomMethod(); 
    } 
    
  2. はの実装を追加します。このクラスと私たちができることを確認するために命名規則に従ってくださいクラスを見つける。

    interface UserRepository extends CrudRepository<User, Long>, CustomUserRepository { 
    
    } 
    

あなたは基本的に選択肢を得る。この方法は:

class UserRepositoryImpl implements CustomUserRepository { 

    private final MongoOperations operations; 

    @Autowired 
    public UserRepositoryImpl(MongoOperations operations) { 

    Assert.notNull(operations, "MongoOperations must not be null!"); 
    this.operations = operations; 
    } 

    public List<User> yourCustomMethod() { 
    // custom implementation here 
    } 
} 
  • 今すぐあなたのベースのリポジトリインターフェースは、カスタム1とインフラが自動的にあなたのカスタム実装を使用する拡張できますだけで簡単にすべてのもの宣言するとUserRepositoryになり、手動で実装した方がCustomUserRepositoryになります。カスタマイズオプションについては、hereと記載されています。

  • +0

    こんにちはオリバー、これは実際には動作しません。 spring-dataは、カスタム名からクエリを自動生成しようとします。 yourCustomMethod()。 "あなたの"はドメインクラスの有効なフィールドではないと言います。私はマニュアルを守り、spring-data-jpa-examplesのやり方を二重にチェックしました。運がない。カスタムインターフェイスをリポジトリクラスに拡張すると、spring-dataは常に自動生成を試みます。唯一の違いは、私がMongoRepositoryを使用していて、CrudRepositoryを使用していないことです。なぜなら、今のところIteratorで作業したくないからです。あなたがヒントを持っていればそれは高く評価されるでしょう。 –

    +4

    最も一般的な間違いは、実装クラスに間違った名前を付けることです:ベースリポジトリのインターフェイスが 'YourRepository'と呼ばれる場合、実装クラスの名前は' YourRepositoryImpl'にする必要があります。それは事実ですか?もしそうなら、私はGitHubなどのサンプルプロジェクトを見てうれしく思います... –

    +1

    こんにちはオリバー、Implクラスはあなたが仮定したように間違った名前が付けられました。私は名前を調整し、それは今働いているように見えます。あなたのフィードバックに感謝します。このように異なる種類のクエリオプションを使用できるようにするのは本当に涼しいです。よく考えました! –

    11

    この回答は少し遅れているかもしれませんが、私はリポジトリ全体のルートを避けることをお勧めします。あなたは、実用的な価値のある実装されたメソッドをほとんど取得しません。それを動作させるには、Java設定のナンセンスを実行します。これは、ドキュメンテーションの多くの助けを借りて何日も何週間も費やすことができます。

    代わりに、MongoTemplateルートを使用し、独自のデータアクセスレイヤーを作成して、Springプログラマが直面する設定の悪夢から解放します。 MongoTemplateは、多くの柔軟性があるので、自分たちのクラスとインタラクションを設計するのが快適なエンジニアのための救世主です。

    1. アプリケーションレベルで実行すると、あなたにMongoClientオブジェクトを与えるMongoClientFactoryクラスを作成します。構造はこのようなものになることができます。これをSingletonとして実装するか、Enum Singleton(スレッドセーフです)を使用することができます。
    2. 各ドメインオブジェクトに対してデータアクセスオブジェクトを継承できるデータアクセスベースクラスを作成します。基本クラスは、すべてのDBアクセスにクラス固有のメソッドが使用できるMongoTemplateオブジェクトを作成するメソッドを実装できます。
    3. 各ドメインオブジェクトの各データアクセスクラスは基本メソッドを実装できます。または、基本クラスで実装できます。
    4. コントローラメソッドは、必要に応じてデータアクセスクラスのメソッドを呼び出すことができます。
    +0

    こんにちは@rameshpa同じプロジェクトでMongoTemplateとリポジトリの両方を使用できますか?使用可能です – Gauranga

    +1

    実装するMongoTemplateはリポジトリで使用される接続とは別のDB接続を持ちます。原子度が問題になる可能性があります。また、シーケンシングのニーズがある場合は、1つのスレッドで2つの異なる接続を使用することをお勧めしません – rameshpa

    関連する問題