MongoTemplate是Spring Data MongoDB封装的MongoDB官方Java驱动,今天给大家分享一下MongoTemplate的实战简单TodoList。本文就不再分享项目的构建过程,所以阅读本文的你,应该先把SpringBoot的项目搭好哦!
MongoDB是一个开源、高性能、无模式的文档型数据库,当初的设计就是用于简化开发和方便扩展,是NoSQL数据库产品中的一种。是最像关系型数据库(MySQL)的非关系型数据库。 它支持的数据结构非常松散,是一种类似于JSON的格式——BSON,所以它既可以存储比较复杂的数据类型,又相当的灵活。 MongoDB中的记录是一个文档,它是一个由字段和值对组成的数据结构。MongoDB文档类似于JSON对象,即一个文档认为就是一个对象。字段的数据类型是字符型,它的值除了使用基本的一些类型外,还可以包括其他文档、普通数组和文档数组。
目录
1. 添加依赖
在本次项目中,笔者采用Gradle进行项目构建,因此在build.gradle文件进行配置。主要是在dependencies中添加mongodb的implementation
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web:2.3.1.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
testImplementation 'org.springframework.boot:spring-boot-starter-test:2.3.1.RELEASE'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2'
testCompile "org.mockito:mockito-core:3.4.0"
}
安装完project的依赖之后,就可以开始我们的实践了!
2. 常用注解
-
@Document
在MongoDB中,有别于常见的关系型数据库,一些术语略有不同,如下表所示:
SQL术语 | MongoDB术语 |
database | database |
table | collection |
row | document |
column | field |
被@Document注解的类,将成为Collection中一个document的映射,使用时引入org.springframework.data.mongodb.core.mapping.Document。如果类名和实际Collection名称不一致(大小写忽略),则需要进行说明,反之则不需要,代码如下:
@Document("t_todo")
public class Todo {
// ...
}
-
@Id
使用该注解标注的字段,将映射为MongoDB中的_id,也就是默认的主键。若当前实体类没有使用@Id注解,则默认将字段名为id的字段映射为_id。注意:使用这个注解的字段类型可以为String或者ObjectId。使用该注解需引入org.springframework.data.annotation.Id。代码如下:
//此处不用该注解也可以,id会自动映射为_id
@Id
private String id;
-
@MongoId
和@Id一样的功能,低版本的依赖需要升级才能使用该注解。使用该注解需引入org.springframework.data.mongodb.core.mapping.MongoId。代码如下:
//此处不用该注解也可以,id会自动映射为_id
@MongoId
private String id;
- @Field
使用该
注解,我们可以将类中名称不一致的字段进行映射。假如在我们的类中,todoContent采用了驼峰式命名,但我们希望映射为todo_content,就可以使用该注解,代码如下。
@Field("create_date")
private String createDate;
- @Transient
使用该注解标注的字段不持久化至数据库中。
3. 创建实体类
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import org.springframework.data.mongodb.core.mapping.MongoId;
@Document
public class Todo {
@MongoId
private String id;
private String content;
private Boolean status = false;
@Field("create_date")
private String createDate;
public Todo() { }
public Todo(String content) {
this.content = content;
}
public String getId() {
return id;
}
public void setId(String _id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Boolean getStatus() {
return status;
}
public void setStatus(Boolean status) {
this.status = status;
}
public String getCreateDate() {
return createDate;
}
public void setCreateDate(String createDate) {
this.createDate = createDate;
}
}
4. 配置MongoDB连接
在application.yml文件中配置,如下所示,当前项目将连接本地27017端口的数据库,并与todoList这一个collection建立联系。
spring:
data:
mongodb:
uri: mongodb://localhost:27017/todoList
5. 增删查改
在进行操作之前,我们在使用MongoTemplate的类中进行注入,笔者在TodoDAO进行该项操作,代码如下:
import org.springframework.data.mongodb.core.MongoTemplate;
@Repository
public class TodoDAO {
@Autowired
MongoTemplate mongoTemplate;
}
5.1. 增加数据
MongoTemplate.save(T objectToSave),可以将一个数据对象保存成一个Mongo的文档记录
import com.todolist.model.Todo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Repository;
import java.text.SimpleDateFormat;
import java.util.Date;
@Repository
public class TodoDAO {
@Autowired
MongoTemplate mongoTemplate;
public TodoDAO(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
public Todo addOne(Todo todo) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
Date createDate = new Date();
todo.setCreateDate(sdf.format(createDate));
return mongoTemplate.save(todo);
}
}
5.2. 查询数据
MongoTemplate.findAll(Class<T> entityClass),查询所有数据,参数是相应的实体类
import com.todolist.model.Todo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class TodoDAO {
@Autowired
MongoTemplate mongoTemplate;
public TodoDAO(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
public List<Todo> findAll() {
return mongoTemplate.findAll(Todo.class);
}
}
5.3. 修改数据
- 首先根据Id查询出document,此处使用Criteria.where("字段名").is("目标值")进行条件查询
- 使用Update中的set("待更新字段名", “更新值”)对查询出的文档进行更新
- 使用MongoTemplate中的updateFirst(Query query, UpdateDefinition update, Class<?> entityClass)进行更新,该方法只更新一条数据;若希望更新所有数据则采用updateMulti()
import com.todolist.model.Todo;
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;
@Repository
public class TodoDAO {
@Autowired
MongoTemplate mongoTemplate;
public TodoDAO(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
public Todo updateById(String id, Todo updateTodo) throws NotFoundException {
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(id));
Update update = new Update();
update.set("status", updateTodo.getStatus());
mongoTemplate.updateFirst(query, update, Todo.class);
return mongoTemplate.findById(id, Todo.class);
}
}
5.4. 删除数据
MongoTemplate中的remove(Object object)可以实现删除数据的需求
import com.todolist.model.Todo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class TodoDAO {
@Autowired
MongoTemplate mongoTemplate;
public TodoDAO(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
public Boolean deleteById(String id) throws NotFoundException {
mongoTemplate.remove(Objects.requireNonNull(mongoTemplate.findById(id, Todo.class)));
return mongoTemplate.findById(id, Todo.class) == null;
}
}
5.5. 分页查询
skip(起始索引).limit(查询条数)搭配,可以实现后台分页查询功能
import com.todolist.model.Todo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class TodoDAO {
@Autowired
MongoTemplate mongoTemplate;
public TodoDAO(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
public List<Todo> findAllByPage(Integer page, Integer pageSize) {
Query query = new Query();
query.skip(page).limit(pageSize);
return mongoTemplate.find(query, Todo.class);
}
}
6. Postman测试
本文重点在MongoTemplate,因此Controller层和Service层的代码直接给出。
- TodoController.java
import com.todolist.exception.NotFoundException;
import com.todolist.model.Todo;
import com.todolist.service.TodoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping(path = "/todos")
public class TodoController {
@Autowired
private TodoService todoService;
@GetMapping
@ResponseStatus(code = HttpStatus.OK)
public List<Todo> getAllTodos(Integer page, Integer pageSize) {
if (page != null || pageSize != null) {
return todoService.findAllByPage(page, pageSize);
}
return todoService.findAll();
}
@GetMapping(path = "/{id}")
@ResponseStatus(code = HttpStatus.OK)
public Todo getAllTodos(@PathVariable String id) {
return todoService.findById(id);
}
@PostMapping
@ResponseStatus(code = HttpStatus.CREATED)
public Todo addTodo(@RequestBody Todo todo) {
return todoService.addOne(todo);
}
@PutMapping(path = "/{id}")
@ResponseStatus(code = HttpStatus.OK)
public Todo updateTodo(@PathVariable String id, @RequestBody Todo todo) throws NotFoundException {
return todoService.updateById(id, todo);
}
@DeleteMapping(path = "/{id}")
@ResponseStatus(code = HttpStatus.OK)
public String deleteTodo(@PathVariable String id) throws NotFoundException {
Boolean result = todoService.deleteById(id);
return result == true ? "Delete success" : "Delete fail";
}
}
- TodoService.java
import com.todolist.dao.TodoDAO;
import com.todolist.exception.NotFoundException;
import com.todolist.model.Todo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
@Service
public class TodoService {
@Autowired
TodoDAO todoDAO;
public TodoService(TodoDAO todoDAO) {
this.todoDAO = todoDAO;
}
public List<Todo> findAll() {
return todoDAO.findAll();
}
public Todo addOne(Todo todo) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
Date createDate = new Date();
todo.setCreateDate(sdf.format(createDate));
return todoDAO.addOne(todo);
}
public Todo updateById(String id, Todo updateTodo) throws NotFoundException {
return todoDAO.updateById(id, updateTodo);
}
public Boolean deleteById(String id) throws NotFoundException {
return todoDAO.deleteById(id);
}
public Todo findById(String id) {
return todoDAO.findById(id);
}
public List<Todo> findAllByPage(Integer page, Integer pageSize) {
int start = (page - 1) * pageSize;
return todoDAO.findAllByPage(start, pageSize);
}
}
6.1. 增加数据
6.2. 查询数据
6.3. 分页查询
6.4. 修改数据
6.5. 删除数据
7. 进阶用法
MongoDB还有非常多的操作,例如聚合查询,海量数据优化,索引的使用等等,本文仅让我们能够使用MongoTemplate实现简单的CRUD操作。如果你的项目比较复杂,那么还需要更多的学习和实践。本文的Demo比较简单,希望能够通俗易懂地让你快速入门MongoTemplate,如有错误,欢迎指出。