MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Wprowadzenie do Spring Data MongoDB

1. Przegląd

Ten artykuł będzie szybkim i praktycznym wprowadzeniem do Spring Data MongoDB.

Omówimy podstawy, korzystając z MongoTemplate a także MongoRepository , z praktycznymi przykładami ilustrującymi każdą operację.


Dalsza lektura:

Obsługa geoprzestrzenna w MongoDB

Zobacz, jak przechowywać, indeksować i przeszukiwać dane geoprzestrzenne za pomocą MongoDBCzytaj więcej →

Testowanie integracji Spring Boot z wbudowaną MongoDB

Dowiedz się, jak korzystać z wbudowanego rozwiązania MongoDB Flapdoodle razem z Spring Boot, aby płynnie przeprowadzać testy integracji MongoDB. Czytaj więcej →

2. MongoTemplate iMongoRepository

Szablon Mongo jest zgodny ze standardowym wzorcem szablonu w Spring i zapewnia gotowy, podstawowy interfejs API do bazowego silnika trwałości.

Repozytorium jest zgodny z podejściem Spring Data-centric i zawiera bardziej elastyczne i złożone operacje API, oparte na dobrze znanych wzorcach dostępu we wszystkich projektach Spring Data.

W obu przypadkach musimy zacząć od zdefiniowania zależności — na przykład w pliku pom.xml , z Mavenem:

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

Aby sprawdzić, czy została wydana jakakolwiek nowa wersja biblioteki, śledź wydania tutaj.

3. Konfiguracja dla MongoTemplate

3.1. Konfiguracja XML

Zacznijmy od prostej konfiguracji XML dla szablonu Mongo:

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

Najpierw musimy zdefiniować ziarno fabryczne odpowiedzialne za tworzenie instancji Mongo.

Następnie musimy faktycznie zdefiniować (i skonfigurować) szablon bean:

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

I na koniec musimy zdefiniować postprocesor, aby przetłumaczyć wszystkie MongoExceptions wrzucony do @Repozytorium klasy z adnotacjami:

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

3.2. Konfiguracja Javy

Stwórzmy teraz podobną konfigurację przy użyciu konfiguracji Java, rozszerzając klasę bazową dla konfiguracji MongoDB AbstractMongoConfiguration :

@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");
    }
}

Pamiętaj, że nie musieliśmy definiować MongoTemplate fasola w poprzedniej konfiguracji, ponieważ jest już zdefiniowana w AbstractMongoClientConfiguration .

Możemy również użyć naszej konfiguracji od podstaw bez rozszerzania 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. Konfiguracja dla MongoRepository

4.1. Konfiguracja XML

Aby skorzystać z niestandardowych repozytoriów (rozszerzenie MongoRepository ), musimy kontynuować konfigurację z sekcji 3.1. i skonfiguruj repozytoria:

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

4.2. Konfiguracja Javy

Podobnie, będziemy budować na konfiguracji, którą już stworzyliśmy w sekcji 3.2. i dodaj nową adnotację do miksu:

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

4.3. Utwórz repozytorium

Po konfiguracji musimy utworzyć repozytorium — rozszerzając istniejące MongoRepository interfejs:

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

Teraz możemy automatycznie połączyć to UserRepository i użyj operacji z MongoRepository lub dodaj niestandardowe operacje.

5. Korzystanie z MongoTemplate

5.1. Wstaw

Zacznijmy od operacji wstawiania oraz od pustej bazy danych:

{
}

Teraz, jeśli wstawimy nowego użytkownika:

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

baza danych będzie wyglądać tak:

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

5.2. Zapisz – wstaw

zapisz operacja ma semantykę zapisz lub zaktualizuj:jeśli identyfikator jest obecny, wykonuje aktualizację, a jeśli nie, wstawia.

Spójrzmy na pierwszą semantykę — wstawkę.

Oto początkowy stan bazy danych:

{
}

Kiedy teraz zapisujemy nowy użytkownik:

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

podmiot zostanie wstawiony do bazy danych:

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

Następnie przyjrzymy się tej samej operacji — zapisz — z aktualizacją semantyki.

5.3. Zapisz – zaktualizuj

Spójrzmy teraz na zapisz z semantyką aktualizacji, działającą na istniejącej encji:

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

Kiedy zapisujemy istniejącego użytkownika, zaktualizujemy go:

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

Baza danych będzie wyglądać tak:

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

Widzimy, że w tym konkretnym przykładzie zapisz używa semantyki aktualizacji ponieważ używamy obiektu o podanym _id .

5.4. Najpierw zaktualizuj

aktualizacjaNajpierw aktualizuje pierwszy dokument pasujący do zapytania.

Zacznijmy od początkowego stanu bazy danych:

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

Kiedy teraz uruchomimy 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);

tylko pierwszy wpis zostanie zaktualizowany:

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

5.5. AktualizujMulti

AktualizujMulti aktualizuje wszystkie dokumenty pasujące do podanego zapytania.

Najpierw stan bazy danych przed wykonaniem updateMulti :

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

Teraz uruchommy updateMulti operacja:

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);

Oba istniejące obiekty zostaną zaktualizowane w bazie danych:

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

5.6. Znajdź i zmodyfikuj

Ta operacja działa jak updateMulti , ale zwraca obiekt przed jego modyfikacją.

Po pierwsze, jest to stan bazy danych przed wywołaniem funkcji findAndModify :

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

Spójrzmy na rzeczywisty kod operacji:

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);

Zwrócony obiekt użytkownika ma takie same wartości jak stan początkowy w bazie danych.

Jest to jednak nowy stan w bazie danych:

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

5.7. Uwaga

wstawka działa na znajdowaniu i modyfikowaniu innych tworzenia semantyki :jeśli dokument jest dopasowany, zaktualizuj go lub utwórz nowy dokument, łącząc zapytanie i obiekt aktualizacji.

Zacznijmy od początkowego stanu bazy danych:

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

Teraz uruchommy 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);

Oto stan bazy danych po operacji:

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

5.8. Usuń

Sprawdzimy stan bazy danych przed wywołaniem remove :

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

Uruchommy teraz usuń :

mongoTemplate.remove(user, "user");

Wynik będzie zgodny z oczekiwaniami:

{
}

6. Korzystanie z MongoRepository

6.1. Wstaw

Najpierw zobaczymy stan bazy danych przed uruchomieniem insert :

{
}

Teraz wstawimy nowego użytkownika:

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

A oto stan końcowy bazy danych:

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

Zwróć uwagę, jak operacja działa tak samo jak wstaw w MongoTemplate API.

6.2. Zapisz Wstaw

Podobnie zapisz działa tak samo jak zapisz działanie w MongoTemplate API.

Zacznijmy od przyjrzenia się semantyce wstawiania operacji.

Oto początkowy stan bazy danych:

{
}

Teraz wykonujemy zapis operacja:

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

Powoduje to dodanie użytkownika do bazy danych:

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

Jeszcze raz zwróć uwagę, jak zapisywać współpracuje z wstaw semantyki, ponieważ wstawiamy nowy obiekt.

6.3. Zapisz Aktualizacja

Przyjrzyjmy się teraz tej samej operacji, ale z aktualizacją semantyki.

Najpierw stan bazy danych przed uruchomieniem nowego zapisu :

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

Teraz wykonujemy operację:

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

Na koniec stan bazy danych:

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

Jeszcze raz zwróć uwagę, jak zapisywać współpracuje z aktualizacją semantyki, ponieważ używamy istniejącego obiektu.

6.4. Usuń

Oto stan bazy danych przed wywołaniem delete :

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

Uruchommy usuń :

userRepository.delete(user);

A oto nasz wynik:

{
}

6.5. Znajdź jeden

Następnie jest to stan bazy danych, gdy findOne nazywa się:

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

Wykonajmy teraz findOne :

userRepository.findOne(user.getId())

A wynik zwróci istniejące dane:

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

6.6. Istnieje

Stan bazy danych przed wywołaniem istnieje :

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

Teraz uruchommy istnieje , co oczywiście zwróci prawdę :

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

6.7. Znajdź wszystko ZSortuj

Stan bazy danych przed wywołaniem funkcji findAll :

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

Uruchommy teraz znajdź wszystko zSortuj :

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

Wynik zostanie posortowany według nazwy w kolejności rosnącej :

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

6.8. Znajdź wszystko Z stronicowalnym

Stan bazy danych przed wywołaniem funkcji findAll :

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

Wykonajmy teraz znajdź wszystko z prośbą o paginację:

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

Wynikowi użytkownicy lista będzie tylko dla jednego użytkownika:

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

7. Adnotacje

Na koniec przyjrzyjmy się również prostym adnotacjom, których Spring Data używa do obsługi tych operacji API.

Poziom pola @Id adnotacja może ozdobić dowolny typ, w tym długi i ciąg :

@Id
private String id;

Jeśli wartość @Id pole nie jest puste, jest przechowywane w bazie danych bez zmian; w przeciwnym razie konwerter założy, że chcemy przechowywać ObjectId w bazie danych (albo ObjectId , Ciąg lub BigInteger pracy).

Następnie przyjrzymy się @Document :

@Document
public class User {
    //
}

Ta adnotacja po prostu oznacza klasę jako obiekt domeny który musi być utrwalony w bazie danych, wraz z umożliwieniem nam wybrania nazwy kolekcji, która ma zostać użyta.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Jak skonfigurować klaster MongoDB obsługujący sesje?

  2. Jakie mechanizmy bezpieczeństwa posiada Meteor?

  3. Uruchom skrypt javascript (plik .js) w mongodb, w tym inny plik w js

  4. Usuń wiele dokumentów z mongo w jednym zapytaniu

  5. importowanie JSON do mongoDB za pomocą pymongo