1. Oversigt
Denne artikel vil være en hurtig og praktisk introduktion til Spring Data MongoDB.
Vi gennemgår det grundlæggende ved at bruge både MongoTemplate samt MongoRepository , med praktiske eksempler til illustration af hver operation.
Yderligere læsning:
Geospatial support i MongoDB
Se, hvordan du gemmer, indekserer og søger geospatiale data med MongoDBRead more →Spring Boot Integration Testing med Embedded MongoDB
Lær, hvordan du bruger Flapdoodles indlejrede MongoDB-løsning sammen med Spring Boot til at køre MongoDB-integrationstests problemfrit. Læs mere →2. MongoTemplate og MongoRepository
MongoTemplate følger standardskabelonmønsteret i foråret og giver en klar til brug, grundlæggende API til den underliggende persistensmotor.
Repository følger den Spring Data-centrerede tilgang og kommer med mere fleksible og komplekse API-operationer, baseret på de velkendte adgangsmønstre i alle Spring Data-projekter.
For begge skal vi starte med at definere afhængigheden - for eksempel i pom.xml , med Maven:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>3.0.3.RELEASE</version>
</dependency> For at kontrollere, om en ny version af biblioteket er blevet frigivet, kan du spore udgivelserne her.
3. Konfiguration for MongoTemplate
3.1. XML-konfiguration
Lad os starte med den simple XML-konfiguration til Mongo-skabelonen:
<mongo:mongo-client id="mongoClient" host="localhost" />
<mongo:db-factory id="mongoDbFactory" dbname="test" mongo-client-ref="mongoClient" /> Vi skal først definere fabriksbønnen, der er ansvarlig for at skabe Mongo-forekomster.
Dernæst skal vi faktisk definere (og konfigurere) skabelonbønnen:
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="mongoDbFactory"/>
</bean> Og endelig skal vi definere en postbehandler til at oversætte alle MongoExceptions smidt i @Repository kommenterede klasser:
<bean class=
"org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/> 3.2. Java-konfiguration
Lad os nu oprette en lignende konfiguration ved hjælp af Java-konfiguration ved at udvide basisklassen for MongoDB-konfiguration 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");
}
} Bemærk, at vi ikke behøvede at definere MongoTemplate bean i den tidligere konfiguration, da den allerede er defineret i AbstractMongoClientConfiguration .
Vi kan også bruge vores konfiguration fra bunden uden at udvide 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. Konfiguration for MongoRepository
4.1. XML-konfiguration
For at gøre brug af brugerdefinerede lagre (for at udvide MongoRepository ), skal vi fortsætte konfigurationen fra afsnit 3.1. og opsæt arkiverne:
<mongo:repositories
base-package="com.baeldung.repository" mongo-template-ref="mongoTemplate"/>
4.2. Java-konfiguration
På samme måde vil vi bygge videre på den konfiguration, vi allerede oprettede i afsnit 3.2. og tilføj en ny annotation til blandingen:
@EnableMongoRepositories(basePackages = "com.baeldung.repository")
4.3. Opret repository
Efter konfigurationen er vi nødt til at oprette et depot – udvide det eksisterende MongoRepository grænseflade:
public interface UserRepository extends MongoRepository<User, String> {
//
} Nu kan vi automatisk forbinde dette UserRepository og brug operationer fra MongoRepository eller tilføje brugerdefinerede handlinger.
5. Brug af MongoTemplate
5.1. Indsæt
Lad os starte med indsættelsesoperationen samt en tom database:
{
} Hvis vi nu indsætter en ny bruger:
User user = new User();
user.setName("Jon");
mongoTemplate.insert(user, "user"); databasen vil se sådan ud:
{
"_id" : ObjectId("55b4fda5830b550a8c2ca25a"),
"_class" : "com.baeldung.model.User",
"name" : "Jon"
} 5.2. Gem – Indsæt
Gem operationen har gem-eller-opdater semantik:hvis et id er til stede, udfører den en opdatering, og hvis ikke, udfører den en indsættelse.
Lad os se på den første semantik — indsættelsen.
Her er den oprindelige tilstand for databasen:
{
} Når vi nu gemmer en ny bruger:
User user = new User();
user.setName("Albert");
mongoTemplate.save(user, "user"); enheden vil blive indsat i databasen:
{
"_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
"_class" : "com.baeldung.model.User",
"name" : "Albert"
} Dernæst vil vi se på den samme handling - gem — med opdateringssemantik.
5.3. Gem – Opdater
Lad os nu se på gem med opdateringssemantik, der fungerer på en eksisterende enhed:
{
"_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
"_class" : "com.baeldung.model.User",
"name" : "Jack"
} Når vi gemmer den eksisterende bruger, opdaterer vi den:
user = mongoTemplate.findOne(
Query.query(Criteria.where("name").is("Jack")), User.class);
user.setName("Jim");
mongoTemplate.save(user, "user"); Databasen vil se sådan ud:
{
"_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
"_class" : "com.baeldung.model.User",
"name" : "Jim"
} Vi kan se, at i dette særlige eksempel, gem bruger semantikken i opdatering fordi vi bruger et objekt med givet _id .
5.4. Opdater først
updateFirst opdaterer det allerførste dokument, der matcher forespørgslen.
Lad os starte med databasens begyndelsestilstand:
[
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Alex"
},
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614c"),
"_class" : "com.baeldung.model.User",
"name" : "Alex"
}
] Når vi nu kører 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); kun den første post vil blive opdateret:
[
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "James"
},
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614c"),
"_class" : "com.baeldung.model.User",
"name" : "Alex"
}
] 5.5. UpdateMulti
UpdateMulti opdaterer alle dokumenter, der matcher den givne forespørgsel.
Først, her er status for databasen, før du udfører updateMulti :
[
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Eugen"
},
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614c"),
"_class" : "com.baeldung.model.User",
"name" : "Eugen"
}
]
Lad os nu køre updateMulti operation:
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); Begge eksisterende objekter vil blive opdateret i databasen:
[
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Victor"
},
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614c"),
"_class" : "com.baeldung.model.User",
"name" : "Victor"
}
] 5.6. FindAndModify
Denne handling fungerer som updateMulti , men det returnerer objektet, før det blev ændret.
For det første er dette databasens tilstand, før du kalder findAndModify :
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Markus"
} Lad os se på den faktiske operationskode:
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); Det returnerede brugerobjekt har de samme værdier som starttilstanden i databasen.
Dette er dog den nye tilstand i databasen:
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Nick"
} 5.7. Ophæv
upsert virker på find og modificer andet opret semantik :hvis dokumentet matches, skal du opdatere det, eller på anden måde oprette et nyt dokument ved at kombinere forespørgslen og opdateringsobjektet.
Lad os starte med databasens begyndelsestilstand:
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Markus"
} Lad os nu køre 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); Her er status for databasen efter operationen:
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Nick"
} 5.8. Fjern
Vi ser på databasens tilstand, før vi kalder fjern :
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Benn"
} Lad os nu køre fjern :
mongoTemplate.remove(user, "user"); Resultatet bliver som forventet:
{
} 6. Brug af MongoRepository
6.1. Indsæt
Først vil vi se databasens tilstand, før vi kører indsæt :
{
} Nu vil vi indsætte en ny bruger:
User user = new User();
user.setName("Jon");
userRepository.insert(user);
Og her er sluttilstanden for databasen:
{
"_id" : ObjectId("55b4fda5830b550a8c2ca25a"),
"_class" : "com.baeldung.model.User",
"name" : "Jon"
} Bemærk, hvordan handlingen fungerer på samme måde som indsæt i MongoTemplate API.
6.2. Gem – Indsæt
På samme måde gem fungerer på samme måde som gem operation i MongoTemplate API.
Lad os starte med at se på indsæt-semantikken af operationen.
Her er den oprindelige tilstand af databasen:
{
} Nu udfører vi gem operation:
User user = new User();
user.setName("Aaron");
userRepository.save(user); Dette resulterer i, at brugeren tilføjes til databasen:
{
"_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
"_class" : "com.baeldung.model.User",
"name" : "Aaron"
} Bemærk igen hvordan gem fungerer med insert semantik, fordi vi indsætter et nyt objekt.
6.3. Gem – Opdatering
Lad os nu se på den samme operation, men med opdater semantik.
Først, her er status for databasen, før du kører den nye gem :
{
"_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
"_class" : "com.baeldung.model.User",
"name" : "Jack"81*6
} Nu udfører vi handlingen:
user = mongoTemplate.findOne(
Query.query(Criteria.where("name").is("Jack")), User.class);
user.setName("Jim");
userRepository.save(user); Endelig er her databasens tilstand:
{
"_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
"_class" : "com.baeldung.model.User",
"name" : "Jim"
} Bemærk igen hvordan gem fungerer med opdatering semantik, fordi vi bruger et eksisterende objekt.
6.4. Slet
Her er status for databasen, før du kalder delete :
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Benn"
} Lad os køre slet :
userRepository.delete(user);
Og her er vores resultat:
{
} 6.5. FindOne
Dernæst er dette databasens tilstand, når findOne hedder:
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Chris"
} Lad os nu udføre findOne :
userRepository.findOne(user.getId())
Og resultatet vil returnere de eksisterende data:
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Chris"
} 6.6. Eksisterer
Status for databasen før opkald findes :
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Harris"
} Lad os nu køre eksisterer , som naturligvis vil returnere sand :
boolean isExists = userRepository.exists(user.getId()); 6.7. Find alle Med Sorter
Status for databasen før kald findAll :
[
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Brendan"
},
{
"_id" : ObjectId("67b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Adam"
}
] Lad os nu køre findAlle med Sorter :
List<User> users = userRepository.findAll(Sort.by(Sort.Direction.ASC, "name")); Resultatet bliver sorteret efter navn i stigende rækkefølge :
[
{
"_id" : ObjectId("67b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Adam"
},
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Brendan"
}
] 6.8. Find alle Med Sidebar
Status for databasen før kald findAll :
[
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Brendan"
},
{
"_id" : ObjectId("67b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Adam"
}
] Lad os nu udføre findAlle med en pagineringsanmodning:
Pageable pageableRequest = PageRequest.of(0, 1);
Page<User> page = userRepository.findAll(pageableRequest);
List<User> users = pages.getContent();
De resulterende brugere listen vil kun være én bruger:
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Brendan"
} 7. Anmærkninger
Lad os endelig også gennemgå de simple annotationer, som Spring Data bruger til at drive disse API-operationer.
Feltniveauet @Id annotering kan dekorere enhver type, inklusive lang og streng :
@Id
private String id; Hvis værdien af @Id feltet er ikke null, det er gemt i databasen, som det er; ellers vil konverteren antage, at vi ønsker at gemme et ObjectId i databasen (enten ObjectId , Streng eller BigInteger arbejde).
Vi vil derefter se på @Document :
@Document
public class User {
//
} Denne annotation markerer simpelthen en klasse som værende et domæneobjekt som skal bevares i databasen, sammen med at vi kan vælge navnet på den samling, der skal bruges.