Spring Boot MongoDB CRUD Example

By | April 5, 2023

CRUD stands for Create, Read, Update, and Delete. The CRUD Operations are the four basic operations that are performed by the software application on the persistence layer. Software applications perform CRUD operations through the use of the Hyper-Text Transfer Protocol (HTTP). These HTTP protocols have methods that are used to create, read, update, or delete data on the persistence layer.

HTTP MethodsCRUDStatus CodeMethod Description
POSTCreate200 (OK)used to create a new resource
GETRead201 (Created)used to fetch or retrieve the resources
PUTUpdate200 (OK)user to update a resource
PATCHModify200 (OK)used to update some fields of a resource
DELETEDelete204 (No Content)used to delete a resource

Spring Boot

Spring Boot is built on the top of Spring framework which means it supports all the features of Spring framework. Spring Boot makes it easy to create standalone, production-grade spring based application that you can “Just Run”. As the standard definition says, Spring Boot provides a production-ready environment, which enables developers to focus more on business logic than configuring projects, setting up servers, etc.

Note: Spring Framework + Embedded Servers - XML Bean Configurations or @Configuration = Spring Boot Architecture
Spring Boot Architecture
Fig 1- Spring Boot Architecture

MongoDB

MongoDB is an open source NoSQL database, which means that unlike SQL, we do not store data in the form of tables and columns, i.e., it will not follow the RDBMS rules. It is a scalable, high-performance, document-oriented database.

Example

In this example, we will create a Task-Manager application using Spring Boot and integrate it with the NoSQL database, i.e., MongoDB. The Task-Manager application is used to create a task and assign it to an assignee.

Step By Step Implementation

Step 1- Create a Spring Boot Project

To create a new project in Spring Boot, please refer to How to Create a Spring Boot Project?

Spring Boot Project
Fig 2- Spring Boot Project Configurations

Step 2- Add Dependencies

We need the following dependencies for our application:

  • Spring Web
  • Spring Data MongoDB
  • Lombok
  • Spring Boot DevTools

Please refer to the below pom.xml file if something is missing.

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.0.5</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.paulsofts</groupId>
	<artifactId>taskmanager</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>taskmanager</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>17</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-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</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>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

Step 3- Create the Package Structures

In this step, we will create the following package in our Spring Boot application, and later on we will add the required classes and interfaces. Please make sure to put every package inside the main package for Spring to do scanning and manage the life cycles of the classes and interfaces.

  • data
  • repository
  • service
  • controller
Spring Boot Project Structure
Fig 3- Package Structure

Step 4- Create Model Class

Create the model class (also known as an entity or POJO class) inside the data package and name it Task. We annotate the Task class with @Document, which marks this class to be mapped with a database, and then store the data in a DOCUMENT type collection. In this class, we define the attributes of the Task class, such as taskId, taskSeverity, taskName, and taskAssignee. We are using the Lombok library to write getter and setter methods.

Java
package com.paulsofts.taskmanager.data;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Document(collection = "tasks")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Task {
	
	@Id
	private int taskId;
	private int taskSeverity;
	private String taskName;
	private String taskAssignee;

}

Step 5- Create Repository Interface

In this step, we create an interface and name it TaskRepository inside our repository package. We will extend this interface with MongoRepository<T, I> where T represents the model class and I represents the type of id we have used in our model class.

Java
package com.paulsofts.taskmanager.repository;

import org.springframework.data.mongodb.repository.MongoRepository;

import com.paulsofts.taskmanager.data.Task;

//we will pass the Task class and the data type of 
//id we have used in our Task class

//MongoRepository will provide the standard CRUD operations
public interface TaskRepository extends MongoRepository<Task, Integer> {

}

Step 6- Create a Service Interface

In this step, we will create an interface called TaskService inside our service package and add the method declarations to create, read, update, and delete a task.

Java
package com.paulsofts.taskmanager.service;

import java.util.List;

import com.paulsofts.taskmanager.data.Task;

public interface TaskService {

	public Task createTask(Task task);
	public Task updateTask(Task task, int taskId);
	public Task getTaskById(int taskId);
	public List<Task> getAllTask();
	public void deleteTask(int taskId);
}

Step 7- Create TaskServiceImpl Class

Now, we will create the corresponding implementation class TaskServiceImpl for the interface TaskService inside our service package. We will add the implementation for the methods of TaskService interface.

Java
package com.paulsofts.taskmanager.service;

import java.util.List;
import java.util.NoSuchElementException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.paulsofts.taskmanager.data.Task;
import com.paulsofts.taskmanager.repository.TaskRepository;

//Annotating this class with the @Service annotation 
//so that its life cycle is managed and handled by the spring container
@Service
public class TaskServiceImpl implements TaskService {
	
	//auto-wiring TaskRepository to perform persistence operations
	@Autowired
	private TaskRepository taskRepository;

	@Override
	public Task createTask(Task task) {
		Task taskSavedToDB = this.taskRepository.save(task);
		return taskSavedToDB;
	}

	@Override
	public Task updateTask(Task task, int taskId) {
		Task taskToBeUpdate = this.taskRepository.findById(taskId).orElseThrow(() -> new NoSuchElementException());
		taskToBeUpdate.setTaskName(task.getTaskName());
		taskToBeUpdate.setTaskSeverity(task.getTaskSeverity());
		taskToBeUpdate.setTaskAssignee(task.getTaskAssignee());
		Task updatedTask = this.taskRepository.save(taskToBeUpdate);
		return updatedTask;
	}

	@Override
	public Task getTaskById(int taskId) {
		Task taskById = this.taskRepository.findById(taskId).orElseThrow(() -> new NoSuchElementException());
		return taskById;
	}

	@Override
	public List<Task> getAllTask() {
		//findAll method will return the list of all the tasks
		List<Task> taskList = this.taskRepository.findAll();
		return taskList;
	}

	@Override
	public void deleteTask(int taskId) {
		this.taskRepository.deleteById(taskId);
	}
}

Step 8- Create Controller Class

We create a new class and name it TaskController inside our controller package, which will be used for request mappings.

Java
package com.paulsofts.taskmanager.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.paulsofts.taskmanager.data.Task;
import com.paulsofts.taskmanager.service.TaskServiceImpl;

@RestController
@RequestMapping("/api/tasks")
public class TaskController {
	
	@Autowired
	private TaskServiceImpl taskServiceImpl;
	
	//Create
	@PostMapping("/create")
	public Task createTask(@RequestBody Task task) {
		Task createdTask = this.taskServiceImpl.createTask(task);
		return createdTask;
	}
	
	//Update
	@PostMapping("/update/{taskId}")
	public Task updateTask(@RequestBody Task task, @PathVariable("taskId") int taskId) {
		Task updatedTask = this.taskServiceImpl.updateTask(task, taskId);
		return updatedTask;
	}
	
	//Get - Single Task
	@GetMapping("/get/{taskId}")
	public Task getTaskById(@PathVariable("taskId") int taskId) {
		Task taskById = this.taskServiceImpl.getTaskById(taskId);
		return taskById;
	}
	
	//Get - All Tasks
	@GetMapping("/get")
	public List<Task> getAllTask(){
		List<Task> taskList =  this.taskServiceImpl.getAllTask();
		return taskList;
	}
	
	//Delete
	@DeleteMapping("/delete")
	public void deleteTask(@PathVariable("taskId") int taskId) {
		this.taskServiceImpl.deleteTask(taskId);
	}
}

Step 9- Update application.properties File

In order to connect our Spring Boot application to MongoDB, we need to add the database configurations to our application.properties file.

XML
spring.data.mongodb.host=localhost
#we are using the default port for mongodb
spring.data.mongodb.port=27017
#the name of database we are using - task_db
spring.data.mongodb.database=task_db

Step 10- Test Application

Now, we run and test our application using Postman.

Create Request

Spring Boot MongoDB CRUD Example
Fig 4- Create Task

Update Request

CRUD Operations
Fig 5- Update Task

Get Request

CRUD Operations
Fig 6- Get Task

GetAll Request

CRUD Operations
Fig 7- Get All Tasks

Delete Task

CRUD Operations
Fig 8- Delete Task

We can also check our MongoDB database using MongoDB Compass. To learn more about how to configure MongoDB, please refer to MongoDB – How to install and configure MongoDB in Windows?

MongoDB
Fig 9- MongoDB Database

Leave a Reply

Your email address will not be published. Required fields are marked *