准备工作
介绍MongoDB与Spring Boo集成,并通过MongoRepository以及MongoTemplate来执行CRUD操作。
Spring Boot:2.3.0.RELEASE Spring Boot Data MongoDB:2.3.0.RELEASE MongoDB:4.2.6 MongoDB Driver:4.0.3
要操作的集合示例数据结构(即model)
Department: String id String name String description Array employees Employee: String empId String name int age double salary one to many relationships
安装MongoDB
- MongoDB快速入门指南与docker-compose快体验
- https://www.yuque.com/ekko/database/dkluyg
创建Spring Boot项目
- SpringBoot2.x快速入门指南(一)
- https://www.yuque.com/ekko/spring/qqt7xd
添加Mongo依赖
代码语言:javascript复制<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
Spring application配置
application.properties
代码语言:javascript复制spring.data.mongodb.username=root
spring.data.mongodb.password=example
spring.data.mongodb.database=admin
测试能否正常启动
host:localhost port:27017 database:admin user:root password:example
项目结构
创建Domain Object
代码语言:javascript复制package com.example.mongodb.model;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.List;
@Document("Department")
public class Department {
@Id
private String id;
@Indexed(name = "deptName")
private String name;
private String description;
@DBRef
private List<Employee> employees;
//...getter setter
}
代码语言:javascript复制package com.example.mongodb.model;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document("Employee")
public class Employee {
@Id
private String empId;
private String name;
private int age;
private double salary;
//...getter setter
}
@Document 标识了要持久化到mongodb的DO。
@Id 文档的唯一标识,在mongodb中是objectId。
@DbRef 关联另一个Document对象,存入的是文档的引用,如果不使用这个注解,存入的是内容。不过即使使用@DbRef,mongodb本身并不维护关联数据,也就是说需要手动将数据插入到被关联文档。
两种操作数据的方式
MongoRepository
代码语言:javascript复制package com.example.mongodb.repository;
import com.example.mongodb.model.Department;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface DepartmentRepository extends MongoRepository<Department,String> {
@Query(value = "{'Employee.name': ?0}", fields = "{'employees' : 0}")
Department findDepartmentByEmployeeName(String empName);
List<Department> findDepartmentByName(String name);
}
MongoTemplate
代码语言:javascript复制package com.example.mongodb.repository;
import com.example.mongodb.model.Department;
import org.springframework.beans.factory.annotation.Autowired;
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 java.util.List;
@Repository
public class DeptRepository {
@Autowired
private MongoTemplate mongoTemplate;
public List<Department> findAll() {
return mongoTemplate.findAll(Department.class);
}
public List<Department> findDepartmentByName(String deptName){
Query query = new Query();
query.addCriteria(Criteria.where("name").is(deptName));
return mongoTemplate.find(query, Department.class);
}
public Department save(Department department) {
mongoTemplate.save(department);
return department;
}
public Department update(Department department){
Query query = new Query();
query.addCriteria(Criteria.where("id").is(department.getId()));
Update update = new Update();
update.set("name", department.getName());
update.set("description", department.getDescription());
return mongoTemplate.findAndModify(query, update, Department.class);
}
public void deleteById(String deptId) {
Query query = new Query();
query.addCriteria(Criteria.where("id").is(deptId));
mongoTemplate.remove(query, Department.class);
}
}
创建Controller
代码语言:javascript复制package com.example.mongodb.controller;
import com.example.mongodb.model.Department;
import com.example.mongodb.model.Employee;
import com.example.mongodb.repository.DepartmentRepository;
import com.example.mongodb.repository.DeptRepository;
import com.example.mongodb.repository.EmpRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@RestController
public class DepartmentController {
@Autowired
DepartmentRepository departmentRepository;
@Autowired
DeptRepository deptRepository;
@Autowired
EmpRepository empRepository;
@PostMapping("/v1/dept/s")
public Department v1save(@RequestBody Department department) {
List<Employee> employees = Optional.ofNullable(department.getEmployees()).orElse(Collections.emptyList());
employees.forEach(employee -> empRepository.save(employee));
return departmentRepository.save(department);
}
@GetMapping("/v1/dept/l")
public List<Department> v1list(){
return departmentRepository.findAll();
}
@PutMapping("/v1/dept/u/{deptId}")
public Department v1update(@RequestBody Department department, @PathVariable String deptId) {
department.setId(deptId);
List<Employee> employees = Optional.ofNullable(department.getEmployees()).orElse(Collections.emptyList());
employees.forEach(employee -> empRepository.save(employee));
return departmentRepository.save(department);
}
@DeleteMapping("/v1/dept/d/{deptId}")
public String v1delete(@PathVariable String deptId) {
departmentRepository.deleteById(deptId);
return deptId;
}
@GetMapping("/v1/dept/get/{deptName}")
public List<Department> v1getByName(@PathVariable String deptName) {
return departmentRepository.findDepartmentByName(deptName);
}
@GetMapping("/v1/dept/get/emp/{empName}")
public Department v1getByEmpName(@PathVariable String empName) {
return departmentRepository.findDepartmentByEmployeeName(empName);
}
@PostMapping("/v2/dept/s")
public Department v2save(Department department) {
List<Employee> employees = Optional.ofNullable(department.getEmployees()).orElse(Collections.emptyList());
employees.forEach(employee -> empRepository.save(employee));
return deptRepository.save(department);
}
@GetMapping("/v2/dept/l")
public List<Department> v2list() {
return deptRepository.findAll();
}
@PutMapping("/v2/dept/u")
public Department v2update(Department department){
List<Employee> employees = Optional.ofNullable(department.getEmployees()).orElse(Collections.emptyList());
employees.forEach(employee -> empRepository.save(employee));
return deptRepository.update(department);
}
@DeleteMapping("/v2/dept/d/{deptId}")
public void v2delete(@PathVariable String deptId) {
deptRepository.deleteById(deptId);
}
@GetMapping("/v2/dept/get/{deptName}")
public List<Department> v2getByName(@PathVariable String deptName){
return deptRepository.findDepartmentByName(deptName);
}
}
v1的接口使用MongoRepository方式操作数据,v2的接口使用MonoTemplate方式操作数据。
测试
代码语言:javascript复制###新增
POST http://localhost:8080/v1/dept/s
Content-Type: application/json
{
"id": "10010",
"name": "中国联通",
"description": "中国联通",
"employees": [
{
"empId": "1",
"name": "jack ma",
"age": 78,
"salary": 900000.0
}
]
}
###更新
PUT http://localhost:8080/v1/dept/u/10010
Content-Type: application/json
{
"id": "10010",
"name": "中国联通",
"description": "中国联通",
"employees": [
{
"empId": "1",
"name": "jack ma",
"age": 78,
"salary": 900000.0
},
{
"empId": "2",
"name": "pony ma",
"age": 78,
"salary": 900000.0
}
]
}
###删除
DELETE http://localhost:8080/v1/dept/d/10010
###查询
GET http://localhost:8080/v1/dept/l
项目地址
持续更新地址:https://www.yuque.com/ekko/spring/yxs4nf
>> 作者: rainbow unicorn