sql >> Databáze >  >> NoSQL >> MongoDB

Úvod do Spring Data MongoDB

1. Přehled

Tento článek bude rychlým a praktickým úvodem Spring Data MongoDB.

Projdeme si základy pomocí MongoTemplate a také MongoRepository s praktickými příklady pro ilustraci každé operace.


Další čtení:

Geoprostorová podpora v MongoDB

Podívejte se, jak ukládat, indexovat a vyhledávat geoprostorová data pomocí MongoDBRPřečtěte si více →

Testování integrace jarního spouštění s vestavěným MongoDB

Naučte se používat vestavěné řešení MongoDB společnosti Flapdoodle spolu s aplikací Spring Boot k hladkému spouštění testů integrace MongoDB. Číst více →

2. MongoTemplate aMongoRepository

Šablona Mongo následuje standardní vzor šablony v Spring a poskytuje základní API připravené k použití základnímu modulu persistence.

Úložiště sleduje Spring Data-centric přístup a přichází s flexibilnějšími a komplexnějšími operacemi API, založenými na dobře známých vzorech přístupu ve všech projektech Spring Data.

U obou musíme začít definováním závislosti — například v pom.xml , s Mavenem:

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

Chcete-li zkontrolovat, zda byla vydána nějaká nová verze knihovny, sledujte vydání zde.

3. Konfigurace pro MongoTemplate

3.1. Konfigurace XML

Začněme jednoduchou konfigurací XML pro šablonu Mongo:

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

Nejprve musíme definovat tovární bean zodpovědný za vytváření instancí Mongo.

Dále musíme skutečně definovat (a nakonfigurovat) šablonu bean:

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

A nakonec musíme definovat postprocesor, který přeloží všechny MongoExceptions vhozené do @Repository anotované třídy:

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

3.2. Konfigurace Java

Pojďme nyní vytvořit podobnou konfiguraci pomocí konfigurace Java rozšířením základní třídy pro konfiguraci 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");
    }
}

Všimněte si, že jsme nemuseli definovat MongoTemplate bean v předchozí konfiguraci, protože je již definován v AbstractMongoClientConfiguration .

Můžeme také použít naši konfiguraci od začátku bez rozšiřování 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. Konfigurace pro MongoRepository

4.1. Konfigurace XML

Chcete-li používat vlastní úložiště (rozšiřující MongoRepository ), musíme pokračovat v konfiguraci z části 3.1. a nastavte úložiště:

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

4.2. Konfigurace Java

Podobně navážeme na konfiguraci, kterou jsme již vytvořili v sekci 3.2. a přidejte do mixu novou anotaci:

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

4.3. Vytvořte úložiště

Po konfiguraci musíme vytvořit úložiště – rozšíření stávajícího MongoRepository rozhraní:

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

Nyní můžeme automaticky připojit toto UserRepository a používat operace z MongoRepository nebo přidat vlastní operace.

5. Pomocí MongoTemplate

5.1. Vložit

Začněme operací vložení a také prázdnou databází:

{
}

Nyní, když vložíme nového uživatele:

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

databáze bude vypadat takto:

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

5.2. Uložit – Vložit

Uložení operace má sémantiku uložení nebo aktualizace:pokud je přítomno id, provede aktualizaci, a pokud ne, provede vložení.

Podívejme se na první sémantiku — vložku.

Zde je počáteční stav databáze:

{
}

Když teď uložíme nový uživatel:

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

entita bude vložena do databáze:

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

Dále se podíváme na stejnou operaci – uložit — se sémantikou aktualizace.

5.3. Uložit – aktualizovat

Podívejme se nyní na uložit se sémantikou aktualizace, fungující na existující entitě:

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

Když ušetříme stávajícího uživatele, aktualizujeme:

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

Databáze bude vypadat takto:

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

Vidíme, že v tomto konkrétním příkladu uložit používá sémantiku aktualizace protože používáme objekt s daným _id .

5.4. UpdateFirst

updateFirst aktualizuje úplně první dokument, který odpovídá dotazu.

Začněme počátečním stavem databáze:

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

Když nyní spustíme 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);

bude aktualizován pouze první záznam:

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

5.5. UpdateMulti

UpdateMulti aktualizuje všechny dokumenty, které odpovídají danému dotazu.

Za prvé, zde je stav databáze před provedením updateMulti :

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

Nyní spustíme updateMulti operace:

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 existující objekty budou v databázi aktualizovány:

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

5.6. FindAndModify

Tato operace funguje jako updateMulti , ale vrátí objekt předtím, než byl upraven.

Za prvé, toto je stav databáze před voláním findAndModify :

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

Podívejme se na skutečný operační kód:

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

Vrácený objekt uživatele má stejné hodnoty jako počáteční stav v databázi.

Toto je však nový stav v databázi:

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

5.7. Nahoru

nahoru funguje na sémantice najít a upravit jinak vytvořit :pokud se dokument shoduje, aktualizujte jej, nebo vytvořte nový dokument kombinací dotazu a objektu aktualizace.

Začněme počátečním stavem databáze:

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

Nyní spustíme 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);

Zde je stav databáze po operaci:

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

5.8. Odstranit

Než zavoláme remove, podíváme se na stav databáze :

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

Nyní spustíme odebrat :

mongoTemplate.remove(user, "user");

Výsledek bude podle očekávání:

{
}

6. Pomocí MongoRepository

6.1. Vložit

Nejprve uvidíme stav databáze před spuštěním vložení :

{
}

Nyní vložíme nového uživatele:

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

A zde je konečný stav databáze:

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

Všimněte si, jak operace funguje stejně jako vložení v MongoTemplate API.

6.2. Uložit Vložit

Podobně uložte funguje stejně jako uložit operace vMongoTemplate API.

Začněme tím, že se podíváme na sémantiku vkládání operace.

Zde je počáteční stav databáze:

{
}

Nyní provedeme uložení operace:

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

Výsledkem je přidání uživatele do databáze:

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

Všimněte si znovu, jak uložit funguje s vložit sémantiku, protože vkládáme nový objekt.

6.3. Uložit Aktualizovat

Podívejme se nyní na stejnou operaci, ale s aktualizací sémantiky

Za prvé, zde je stav databáze před spuštěním nového uložení :

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

Nyní provedeme operaci:

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

Nakonec zde je stav databáze:

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

Všimněte si znovu, jak uložit funguje s aktualizací sémantiku, protože používáme existující objekt.

6.4. Smazat

Zde je stav databáze před voláním delete :

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

Spusťte delete :

userRepository.delete(user);

A tady je náš výsledek:

{
}

6.5. FindOne

Dále toto je stav databáze při findOne se jmenuje:

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

Nyní spusťte findOne :

userRepository.findOne(user.getId())

A výsledek vrátí existující data:

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

6.6. Existuje

Stav databáze před voláním existuje :

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

Nyní spustíme existuje , což samozřejmě vrátí true :

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

6.7. Najít vše Pomocí Řadit

Stav databáze před voláním findAll :

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

Nyní spustíme findAll sTřídit :

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

Výsledek bude seřazen vzestupně podle názvu :

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

6.8. Najít vše S Stránkovatelný

Stav databáze před voláním findAll :

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

Nyní spusťte findAll s požadavkem na stránkování:

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

Výslední uživatelé seznam bude pouze jeden uživatel:

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

7. Anotace

Nakonec si také projdeme jednoduché anotace, které Spring Data používá k řízení těchto operací API.

Úroveň pole @Id anotace může zdobit jakýkoli typ, včetně dlouhého a řetězec :

@Id
private String id;

Pokud je hodnota @Id pole není null, je uloženo v databázi tak, jak je; jinak bude převodník předpokládat, že chceme uložit ObjectId v databázi (buď ObjectId , Řetězec nebo BigInteger práce).

Dále se podíváme na @Document :

@Document
public class User {
    //
}

Tato anotace jednoduše označí třídu jako objekt domény které je třeba uchovat v databázi a zároveň nám umožňuje vybrat název kolekce, která se má použít.


  1. moje redis klíče nevyprší

  2. Zkombinujte dvě instance Redis do jedné instance se dvěma databázemi

  3. Pokud je redis již součástí zásobníku, proč se Memcached stále používá spolu s Redis?

  4. Vložte Pandas Dataframe do mongodb pomocí PyMongo