1. 概要

この記事は、SpringDataMongoDBの簡単で実用的な紹介になります。

MongoTemplateMongoRepositoryの両方を使用して基本を確認し、実際の例を使用して各操作を説明します。

2. MongoTemplateおよびMongoRepository

MongoTemplate は、Springの標準テンプレートパターンに従い、基盤となる永続化エンジンにすぐに使用できる基本的なAPIを提供します。

リポジトリはSpringData中心のアプローチに従い、すべてのSpring Dataプロジェクトでよく知られているアクセスパターンに基づいて、より柔軟で複雑なAPI操作を備えています。

どちらの場合も、依存関係を定義することから始める必要があります。たとえば、 pom.xml で、Mavenを使用します。

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-mongodb</artifactId>
    <version>3.0.3.RELEASE</version>
</dependency>

ライブラリの新しいバージョンがリリースされているかどうかを確認するには、ここでリリースを追跡します

3. MongoTemplateの構成

3.1. XML構成

Mongoテンプレートの単純なXML構成から始めましょう。

<mongo:mongo-client id="mongoClient" host="localhost" />
<mongo:db-factory id="mongoDbFactory" dbname="test" mongo-client-ref="mongoClient" />

最初に、Mongoインスタンスの作成を担当するファクトリBeanを定義する必要があります。

次に、テンプレートBeanを実際に定義(および構成)する必要があります。

<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> 
    <constructor-arg ref="mongoDbFactory"/> 
</bean>

そして最後に、@Repository注釈付きクラスでスローされたMongoExceptionsを変換するポストプロセッサを定義する必要があります。

<bean class=
  "org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

3.2. Java構成

ここで、MongoDB構成 AbstractMongoConfiguration の基本クラスを拡張して、Java構成を使用して同様の構成を作成しましょう。

@Configuration
public class MongoConfig extends AbstractMongoClientConfiguration {
 
    @Override
    protected String getDatabaseName() {
        return "test";
    }
 
    @Override
    public MongoClient mongoClient() {
        ConnectionString connectionString = new ConnectionString("mongodb://localhost:27017/test");
        MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
            .applyConnectionString(connectionString)
            .build();
        
        return MongoClients.create(mongoClientSettings);
    }
 
    @Override
    public Collection getMappingBasePackages() {
        return Collections.singleton("com.baeldung");
    }
}

AbstractMongoClientConfiguration ですでに定義されているため、以前の構成で MongoTemplatebeanを定義する必要がなかったことに注意してください。

AbstractMongoClientConfiguration を拡張せずに、構成を最初から使用することもできます。

@Configuration
public class SimpleMongoConfig {
 
    @Bean
    public MongoClient mongo() {
        ConnectionString connectionString = new ConnectionString("mongodb://localhost:27017/test");
        MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
          .applyConnectionString(connectionString)
          .build();
        
        return MongoClients.create(mongoClientSettings);
    }

    @Bean
    public MongoTemplate mongoTemplate() throws Exception {
        return new MongoTemplate(mongo(), "test");
    }
}

4. MongoRepositoryの構成

4.1. XML構成

カスタムリポジトリを利用するには( MongoRepository を拡張)、セクション3.1から構成を続行する必要があります。 リポジトリを設定します。

<mongo:repositories 
  base-package="com.baeldung.repository" mongo-template-ref="mongoTemplate"/>

4.2. Java構成

同様に、セクション3.2ですでに作成した構成に基づいて構築します。 ミックスに新しい注釈を追加します。

@EnableMongoRepositories(basePackages = "com.baeldung.repository")

4.3. リポジトリを作成する

構成後、リポジトリを作成する必要があります—既存のMongoRepositoryインターフェースを拡張します。

public interface UserRepository extends MongoRepository<User, String> {
    // 
}

これで、この UserRepository を自動配線して、 MongoRepository の操作を使用したり、カスタム操作を追加したりできます。

5. MongoTemplateを使用する

5.1。挿入

挿入操作と空のデータベースから始めましょう。

{
}

ここで、新しいユーザーを挿入すると、次のようになります。

User user = new User();
user.setName("Jon");
mongoTemplate.insert(user, "user");

データベースは次のようになります。

{
    "_id" : ObjectId("55b4fda5830b550a8c2ca25a"),
    "_class" : "com.baeldung.model.User",
    "name" : "Jon"
}

5.2. 保存–挿入

save 操作には、保存または更新のセマンティクスがあります。IDが存在する場合は更新を実行し、存在しない場合は挿入を実行します。

最初のセマンティクスである挿入を見てみましょう。

データベースの初期状態は次のとおりです

{
}

新しいユーザーを保存すると、次のようになります。

User user = new User();
user.setName("Albert"); 
mongoTemplate.save(user, "user");

エンティティはデータベースに挿入されます。

{
    "_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
    "_class" : "com.baeldung.model.User",
    "name" : "Albert"
}

次に、同じ操作— save —を更新セマンティクスで見ていきます。

5.3. 保存–更新

次に、既存のエンティティで動作する、更新セマンティクスを使用したsaveを見てみましょう。

{
    "_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
    "_class" : "com.baeldung.model.User",
    "name" : "Jack"
}

既存のユーザーを保存すると、次のように更新されます。

user = mongoTemplate.findOne(
  Query.query(Criteria.where("name").is("Jack")), User.class);
user.setName("Jim");
mongoTemplate.save(user, "user");

データベースは次のようになります。

{
    "_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
    "_class" : "com.baeldung.model.User",
    "name" : "Jim"
}

この特定の例では、 _id が指定されたオブジェクトを使用しているため、saveupdateのセマンティクスを使用していることがわかります。

5.4. UpdateFirst

updateFirst は、クエリに一致する最初のドキュメントを更新します。

データベースの初期状態から始めましょう。

[
    {
        "_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
        "_class" : "com.baeldung.model.User",
        "name" : "Alex"
    },
    {
        "_id" : ObjectId("55b5ffa5511fee0e45ed614c"),
        "_class" : "com.baeldung.model.User",
        "name" : "Alex"
    }
]

updateFirst を実行すると、次のようになります。

Query query = new Query();
query.addCriteria(Criteria.where("name").is("Alex"));
Update update = new Update();
update.set("name", "James");
mongoTemplate.updateFirst(query, update, User.class);

最初のエントリのみが更新されます。

[
    {
        "_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
        "_class" : "com.baeldung.model.User",
        "name" : "James"
    },
    {
        "_id" : ObjectId("55b5ffa5511fee0e45ed614c"),
        "_class" : "com.baeldung.model.User",
        "name" : "Alex"
    }
]

5.5. UpdateMulti

UpdateMulti 指定されたクエリに一致するすべてのドキュメントを更新します。

まず、updateMultiを実行する前のデータベースの状態を次に示します。

[
    {
        "_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
        "_class" : "com.baeldung.model.User",
        "name" : "Eugen"
    },
    {
        "_id" : ObjectId("55b5ffa5511fee0e45ed614c"),
        "_class" : "com.baeldung.model.User",
        "name" : "Eugen"
    }
]

次に、updateMulti操作を実行してみましょう。

Query query = new Query();
query.addCriteria(Criteria.where("name").is("Eugen"));
Update update = new Update();
update.set("name", "Victor");
mongoTemplate.updateMulti(query, update, User.class);

既存の両方のオブジェクトがデータベースで更新されます。

[
    {
        "_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
        "_class" : "com.baeldung.model.User",
        "name" : "Victor"
    },
    {
        "_id" : ObjectId("55b5ffa5511fee0e45ed614c"),
        "_class" : "com.baeldung.model.User",
        "name" : "Victor"
    }
]

5.6. FindAndModify

この操作はupdateMultiのように機能しますが、は変更前のオブジェクトを返します。

まず、これはfindAndModifyを呼び出す前のデータベースの状態です。

{
    "_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
    "_class" : "com.baeldung.model.User",
    "name" : "Markus"
}

実際のオペコードを見てみましょう。

Query query = new Query();
query.addCriteria(Criteria.where("name").is("Markus"));
Update update = new Update();
update.set("name", "Nick");
User user = mongoTemplate.findAndModify(query, update, User.class);

返されるユーザーオブジェクトは、データベースの初期状態と同じ値です。

ただし、これはデータベースの新しい状態です。

{
    "_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
    "_class" : "com.baeldung.model.User",
    "name" : "Nick"
}

5.7. アップサート

upsert は、 find and modify else createセマンティクスで機能します。ドキュメントが一致する場合は、ドキュメントを更新するか、クエリと更新オブジェクトを組み合わせて新しいドキュメントを作成します。

データベースの初期状態から始めましょう。

{
    "_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
    "_class" : "com.baeldung.model.User",
    "name" : "Markus"
}

それでは、upsertを実行してみましょう。

Query query = new Query();
query.addCriteria(Criteria.where("name").is("Markus"));
Update update = new Update();
update.set("name", "Nick");
mongoTemplate.upsert(query, update, User.class);

操作後のデータベースの状態は次のとおりです。

{
    "_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
    "_class" : "com.baeldung.model.User",
    "name" : "Nick"
}

5.8. 削除

remove を呼び出す前に、データベースの状態を確認します。

{
    "_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
    "_class" : "com.baeldung.model.User",
    "name" : "Benn"
}

removeを実行してみましょう。

mongoTemplate.remove(user, "user");

結果は期待どおりになります。

{
}

6. MongoRepositoryを使用する

6.1. 挿入

まず、insertを実行する前にデータベースの状態を確認します。

{
}

次に、新しいユーザーを挿入します。

User user = new User();
user.setName("Jon");
userRepository.insert(user);

そして、これがデータベースの最終状態です。

{
    "_id" : ObjectId("55b4fda5830b550a8c2ca25a"),
    "_class" : "com.baeldung.model.User",
    "name" : "Jon"
}

MongoTemplateAPIのinsertと同じように操作が機能することに注意してください。

6.2. 保存挿入

同様に、 save は、 MongoTemplateAPIのsave操作と同じように機能します。

まず、操作の挿入セマンティクスを見てみましょう。

データベースの初期状態は次のとおりです。

{
}

次に、save操作を実行します。

User user = new User();
user.setName("Aaron");
userRepository.save(user);

これにより、ユーザーがデータベースに追加されます。

{
    "_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
    "_class" : "com.baeldung.model.User",
    "name" : "Aaron"
}

新しいオブジェクトを挿入しているため、saveinsertセマンティクスとどのように連携するかに再度注意してください。

6.3. 保存更新

同じ操作をupdateセマンティクスで見てみましょう。

まず、新しいsaveを実行する前のデータベースの状態を次に示します。

{
    "_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
    "_class" : "com.baeldung.model.User",
    "name" : "Jack"81*6
}

次に、操作を実行します。

user = mongoTemplate.findOne(
  Query.query(Criteria.where("name").is("Jack")), User.class);
user.setName("Jim");
userRepository.save(user);

最後に、データベースの状態は次のとおりです。

{
    "_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
    "_class" : "com.baeldung.model.User",
    "name" : "Jim"
}

既存のオブジェクトを使用しているため、saveupdateセマンティクスとどのように連携するかに再度注意してください。

6.4. 削除

deleteを呼び出す前のデータベースの状態は次のとおりです。

{
    "_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
    "_class" : "com.baeldung.model.User",
    "name" : "Benn"
}

delete を実行してみましょう:

userRepository.delete(user);

そして、これが私たちの結果です:

{
}

6.5. FindOne

次に、これはfindOneが呼び出されたときのデータベースの状態です。

{
    "_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
    "_class" : "com.baeldung.model.User",
    "name" : "Chris"
}

findOneを実行してみましょう。

userRepository.findOne(user.getId())

そして、結果は既存のデータを返します:

{
    "_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
    "_class" : "com.baeldung.model.User",
    "name" : "Chris"
}

6.6. 存在

excistsを呼び出す前のデータベースの状態:

{
    "_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
    "_class" : "com.baeldung.model.User",
    "name" : "Harris"
}

次に、 examples を実行してみましょう。これにより、もちろんtrueが返されます。

boolean isExists = userRepository.exists(user.getId());

6.7. FindAll W ith Sort

findAll を呼び出す前のデータベースの状態:

[
    {
        "_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
        "_class" : "com.baeldung.model.User",
        "name" : "Brendan"
    },
    {
       "_id" : ObjectId("67b5ffa5511fee0e45ed614b"),
       "_class" : "com.baeldung.model.User",
       "name" : "Adam"
    }
]

findAll with Sortを実行してみましょう。

List<User> users = userRepository.findAll(Sort.by(Sort.Direction.ASC, "name"));

結果は名前の昇順で並べ替えられます

[
    {
        "_id" : ObjectId("67b5ffa5511fee0e45ed614b"),
        "_class" : "com.baeldung.model.User",
        "name" : "Adam"
    },
    {
        "_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
        "_class" : "com.baeldung.model.User",
        "name" : "Brendan"
    }
]

6.8. FindAll W ithページング可能

findAll を呼び出す前のデータベースの状態:

[
    {
        "_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
        "_class" : "com.baeldung.model.User",
        "name" : "Brendan"
    },
    {
        "_id" : ObjectId("67b5ffa5511fee0e45ed614b"),
        "_class" : "com.baeldung.model.User",
        "name" : "Adam"
    }
]

ここで、ページ付け要求を使用してfindAllを実行してみましょう。

Pageable pageableRequest = PageRequest.of(0, 1);
Page<User> page = userRepository.findAll(pageableRequest);
List<User> users = pages.getContent();

結果のusersリストは1人のユーザーのみになります:

{
    "_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
    "_class" : "com.baeldung.model.User",
    "name" : "Brendan"
}

7. 注釈

最後に、Spring DataがこれらのAPI操作を駆動するために使用する簡単なアノテーションについても見ていきましょう。

フィールドレベルの@Idアノテーションは、longstringなど、あらゆるタイプを装飾できます。

@Id
private String id;

@Id フィールドの値がnullでない場合、データベースにそのまま保存されます。 それ以外の場合、コンバーターは、 ObjectId をデータベースに格納することを想定します( ObjectId StringまたはBigInteger work)。

次に、@Documentを見ていきます。

@Document
public class User {
    //
}

このアノテーションは、使用するコレクションの名前を選択できるようにするとともに、データベースに永続化する必要があるドメインオブジェクトとしてクラスを単にマークします。

8. 結論

この記事は、 MongoTemplate APIと、 MongoRepository の両方を使用して、SpringDataでMongoDBを使用するための簡単で包括的な紹介でした。

これらすべての例とコードスニペットの実装は、GitHubにあります。