Le Tutoriel de Spring Boot et MongoDB
View more Tutorials:


Dans cette leçon, je vais vous montrer comment créer une application Spring Boot connectée à la base de données MongoDB et apprendre de Spring data MongoDB.
Sur Eclipse, créez un projet Spring Boot.



pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.o7planning</groupId>
<artifactId>SpringBootMongoDB</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>SpringBootMongoDB</name>
<description>Spring Boot +MongoDB</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Afin que Spring Boot soit capable de se connecter à la base de données MongoDB, vous devez configurer les propriétés (properity) dans le fichier applications.properties.
application.properties
#mongodb
spring.data.mongodb.host=192.168.254.129
spring.data.mongodb.port=27017
spring.data.mongodb.database=mydatabase
#logging
logging.level.org.springframework.data=debug
logging.level.=error
Dans cette application, je me connecte à "mydatabase" de MongoDB. Ne vous inquiétez pas si "mydatabase" n'existe pas, il sera automatiquement créé.
Spring Data MongoDB est une bibliothèque de Spring, il vous aide de travailler plus facilement avec MongoDB. Par exemple, vous avez un Collection T et vous voulez créer une classe ayant 4 fonctionnements tels que la requête, l'ajout, la modification, la suppression sur cette Collection. Il est très simple!
Selon la règle de Spring Data MongoDB vous devez seulement définir une interface étendue de l'interface MongoRepository<T,ID>, et déclarer les méthodes de déclaration de données sur cette Collection. Spring Data MongoDB va créer une classe qui implémente (implements) cette interface là pour vous. Bien sur, le nom de ces méthodes doit suivre la règle que Spring Data MongoDB crée.
Selon la règle de Spring Data MongoDB vous devez seulement définir une interface étendue de l'interface MongoRepository<T,ID>, et déclarer les méthodes de déclaration de données sur cette Collection. Spring Data MongoDB va créer une classe qui implémente (implements) cette interface là pour vous. Bien sur, le nom de ces méthodes doit suivre la règle que Spring Data MongoDB crée.
Par exemple, sur la base de données, nous avons la collection Employee, qui est équivalent à la classe Employee de Java. Les champs (field) de cette collection est équivalent aux champs (field) de la classe Employee. Le champ ID est la clé principale (primary key).

Employee.java
package org.o7planning.sbmongodb.document;
import java.util.Date;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
@Document(collection = "Employee")
public class Employee {
@Id
private Long id;
@Indexed(unique = true)
@Field(value = "Emp_No")
private String empNo;
@Field(value = "Full_Name")
private String fullName;
@Field(value = "Hire_Date")
private Date hireDate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getEmpNo() {
return empNo;
}
public void setEmpNo(String empNo) {
this.empNo = empNo;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public Date getHireDate() {
return hireDate;
}
public void setHireDate(Date hireDate) {
this.hireDate = hireDate;
}
@Override
public String toString() {
return "id:" + this.id + ", empNo: " + empNo //
+ ", fullName: " + this.fullName + ", hireDate: " + this.hireDate;
}
}
L'interface EmployeeRepository étend (extends) de l'interface MongoRepository<Employee, Long>. Il a des méthodes de manipulation avec la collection Employee. Spring Data MongoDB va automatiquement créer une classe qui implémente (implements) cette interface en même temps de l'exécution de l'application.
EmployeeRepository.java
package org.o7planning.sbmongodb.repository;
import java.util.Date;
import java.util.List;
import org.o7planning.sbmongodb.document.Employee;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
// This is an Interface.
// No need Annotation here
public interface EmployeeRepository extends MongoRepository<Employee, Long> { // Long: Type of Employee ID.
Employee findByEmpNo(String empNo);
List<Employee> findByFullNameLike(String fullName);
List<Employee> findByHireDateGreaterThan(Date hireDate);
// Supports native JSON query string
@Query("{fullName:'?0'}")
List<Employee> findCustomByFullName(String fullName);
}
Spring Data MongoDB va automatiquement créer des méthodes qui implémente les méthodes abstraites de l'interface. Voici est la liste des mots clés supportés pour les méthodes de requête de données :
Keyword | Sample | Logical result |
---|---|---|
GreaterThan | findByAgeGreaterThan(int age) | {"age" : {"$gt" : age}} |
LessThan | findByAgeLessThan(int age) | {"age" : {"$lt" : age}} |
Between | findByAgeBetween(int from, int to) | {"age" : {"$gt" : from, "$lt" : to}} |
IsNotNull, NotNull | findByFirstnameNotNull() | {"age" : {"$ne" : null}} |
IsNull, Null | findByFirstnameNull() | {"age" : null} |
Like | findByFirstnameLike(String name) | {"age" : age} ( age as regex) |
(No keyword) | findByFirstname(String name) | {"age" : name} |
Not | findByFirstnameNot(String name) | {"age" : {"$ne" : name}} |
Near | findByLocationNear(Point point) | {"location" : {"$near" : [x,y]}} |
Within | findByLocationWithin(Circle circle) | {"location" : {"$within" : {"$center" : [ [x, y], distance]}}} |
Within | findByLocationWithin(Box box) | {"location" : {"$within" : {"$box" : [ [x1, y1], x2, y2]}}} |
Vous pouvez également créer des interfaces avec des méthodes personnalisées. En ce cas, vous devez écrire la classe qui implémente (implements) cette interface là.
EmployeeRepositoryCustom.java
package org.o7planning.sbmongodb.repository;
import java.util.Date;
public interface EmployeeRepositoryCustom {
public long getMaxEmpId();
public long updateEmployee(String empNo, String fullName, Date hireDate);
}
EmployeeRepositoryCustomImpl.java
package org.o7planning.sbmongodb.repository;
import java.util.Date;
import org.o7planning.sbmongodb.document.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import com.mongodb.client.result.UpdateResult;
@Repository
public class EmployeeRepositoryCustomImpl implements EmployeeRepositoryCustom {
@Autowired
MongoTemplate mongoTemplate;
public long getMaxEmpId() {
Query query = new Query();
query.with(new Sort(Sort.Direction.DESC, "id"));
query.limit(1);
Employee maxObject = mongoTemplate.findOne(query, Employee.class);
if (maxObject == null) {
return 0L;
}
return maxObject.getId();
}
@Override
public long updateEmployee(String empNo, String fullName, Date hireDate) {
Query query = new Query(Criteria.where("empNo").is(empNo));
Update update = new Update();
update.set("fullName", fullName);
update.set("hireDate", hireDate);
UpdateResult result = this.mongoTemplate.updateFirst(query, update, Employee.class);
if (result != null) {
return result.getModifiedCount();
}
return 0;
}
}
SpringBootMongoDbApplication.java
package org.o7planning.sbmongodb;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
@SpringBootApplication
public class SpringBootMongoDbApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootMongoDbApplication.class, args);
}
@Bean
public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory, MongoMappingContext context) {
MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(mongoDbFactory), context);
converter.setTypeMapper(new DefaultMongoTypeMapper(null));
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory, converter);
return mongoTemplate;
}
}
MainController.java
package org.o7planning.sbmongodb.controller;
import java.util.Date;
import java.util.List;
import org.o7planning.sbmongodb.document.Employee;
import org.o7planning.sbmongodb.repository.EmployeeRepository;
import org.o7planning.sbmongodb.repository.EmployeeRepositoryCustom;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MainController {
private static final String[] NAMES = { "Tom", "Jerry", "Donald" };
@Autowired
private EmployeeRepositoryCustom employeeRepositoryCustom;
@Autowired
private EmployeeRepository employeeRepository;
@ResponseBody
@RequestMapping("/")
public String home() {
String html = "";
html += "<ul>";
html += " <li><a href='/testInsert'>Test Insert</a></li>";
html += " <li><a href='/showAllEmployee'>Show All Employee</a></li>";
html += " <li><a href='/showFullNameLikeTom'>Show All 'Tom'</a></li>";
html += " <li><a href='/deleteAllEmployee'>Delete All Employee</a></li>";
html += "</ul>";
return html;
}
@ResponseBody
@RequestMapping("/testInsert")
public String testInsert() {
Employee employee = new Employee();
long id = this.employeeRepositoryCustom.getMaxEmpId() + 1;
int idx = (int) (id % NAMES.length);
String fullName = NAMES[idx] + " " + id;
employee.setId(id);
employee.setEmpNo("E" + id);
employee.setFullName(fullName);
employee.setHireDate(new Date());
this.employeeRepository.insert(employee);
return "Inserted: " + employee;
}
@ResponseBody
@RequestMapping("/showAllEmployee")
public String showAllEmployee() {
List<Employee> employees = this.employeeRepository.findAll();
String html = "";
for (Employee emp : employees) {
html += emp + "<br>";
}
return html;
}
@ResponseBody
@RequestMapping("/showFullNameLikeTom")
public String showFullNameLikeTom() {
List<Employee> employees = this.employeeRepository.findByFullNameLike("Tom");
String html = "";
for (Employee emp : employees) {
html += emp + "<br>";
}
return html;
}
@ResponseBody
@RequestMapping("/deleteAllEmployee")
public String deleteAllEmployee() {
this.employeeRepository.deleteAll();
return "Deleted!";
}
}
