Руководство Spring Boot и MongoDB
View more Tutorials:
В данной статье я покажу вам как создать приложение Spring Boot подключенное к базе данных MongoDB. И изучить про Spring data MongoDB.
На Eclipse создать проект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>
Чтобы Spring Boot смог подключиться к базе данных MongoDB вы конфигурируете свойства (properity) в файле 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
В данном приложении, я подключаюсь к "mydatabase" у MongoDB, вам не нужно волноваться, если "mydatabase" не существует, он будет автоматически создан.
Spring Data MongoDB является библиотекой у Spring, она позволяет вам легко работать с MongoDB. Например у вас есть Collection T и вы хотите создать Class с 4-мя функциями запрос добавить, редактировать, удалить на данном Collection? Очень просто!
По принципу Spring Data MongoDB вам нужно только определить расширенный интерфейс MongoRepository<T,ID> интерфейс, и объявить методы для манипуляции с данными этого Collection. Spring Data MongoDB создаст класс применения (implements) того интерфейса для вас. Конечно названия методов должны следовать правилам данные Spring Data MongoDB.
По принципу Spring Data MongoDB вам нужно только определить расширенный интерфейс MongoRepository<T,ID> интерфейс, и объявить методы для манипуляции с данными этого Collection. Spring Data MongoDB создаст класс применения (implements) того интерфейса для вас. Конечно названия методов должны следовать правилам данные Spring Data MongoDB.
Например на базе данных мы имеем collection Employee, соответствующий классу Employee у Java. Поля (field) данногоcollection будут соответствовать с полями (field) класса Employee. Поле ID это основной класс (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; } }
Интерфейс EmployeeRepository расширяет (extends) интерфейс MongoRepository<Employee, Long>, он имеет методы для манипуляции с collection Employee. Spring Data MongoDB автоматически создает класс применения (implements) данного интерфейса во время запуска приложения.
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 автоматически создаст методы применения абстрактных методов интерфейса. Ниже является список ключевых слов поддерживающих методы запроса данных:
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]}}} |
Помимо этого вы так же можете создать интерфейсы с кастомизированными методами. В данной ситуации вы должны сами написать класс применения (implements) того интерфейса.
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!"; } }
