Spring Boot MongoDB CRUD
JavaSpring Boot

MongoDB CRUD operations in a spring boot app simplified

In this BitsToGigs post we’ll explore MongoDB CRUD operations (Create, Read, Update, Delete) in the context of a Spring Boot application. MongoDB is a popular NoSQL database that stores data in a flexible, JSON-like format known as BSON (Binary JSON). Spring Boot, on the other hand, is a framework that simplifies the development of Java applications, making it easy to create stand-alone, production-grade Spring-based applications.

MongoDB CRUD operations simplified

MongoDB CRUD operations involve creating, reading, updating, and deleting documents in a MongoDB collection. In a Spring Boot application, we can use the Spring Data MongoDB library to interact with MongoDB. Spring Data MongoDB provides a high-level abstraction for MongoDB, allowing developers to perform CRUD operations using Java objects.

Setting up the Spring Boot Project

Before diving into CRUD operations, let’s set up a basic Spring Boot project with MongoDB integration. You can use Spring Initializer (https://start.spring.io/) to generate a new project with the following dependencies:

  • Spring Web
  • Spring Data MongoDB

Once the project is generated, import it into your favorite IDE and proceed with the implementation.

You can also manually add the mentioned dependencies in a Spring Boot application. You can achieve this by adding the following dependencies in your pom.xml file if you are using Maven or build.gradle if you are using Gradle.

Maven Dependencies:

<!-- Spring Boot Starter Web for building web applications -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Spring Data MongoDB for MongoDB integration -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

Gradle Dependencies:

// Spring Boot Starter Web for building web applications
implementation 'org.springframework.boot:spring-boot-starter-web'

// Spring Data MongoDB for MongoDB integration
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'

These dependencies include the Spring Boot Starter Web, which is essential for building web applications, and the Spring Boot Starter Data MongoDB, which provides integration with MongoDB through Spring Data.

Connecting to MongoDB

After adding these dependencies, your Spring Boot application will be equipped to work with MongoDB. Remember to customize your MongoDB configuration in the application.properties or application.yml file, as mentioned in the previous response:

In your application.properties file, configure the MongoDB connection properties:

spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=mydatabase

Replace the values with your MongoDB server details.

Create Operation

Let’s start with the Create (Insert) operation. In Spring Data MongoDB, creating a new document involves saving a Java object to a MongoDB collection.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/users")
public class UserController {

    @Autowired
    private UserRepository userRepository;

    @PostMapping
    public User createUser(@RequestBody User user) {
        return userRepository.save(user);
    }
}

In the above example, we use @PostMapping to handle HTTP POST requests for creating a new user. The @RequestBody annotation binds the HTTP request body to the User object.

Read Operation

Reading data from MongoDB is done using various query methods provided by Spring Data MongoDB. Let’s retrieve a user by their ID.

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@RestController
@RequestMapping("/api/users")
public class UserController {

    // (previous code)

    @GetMapping("/{id}")
    public User getUserById(@PathVariable String id) {
        return userRepository.findById(id).orElse(null);
    }
}

Here, @GetMapping("/{id}") maps the endpoint to handle HTTP GET requests with a path variable for the user ID.

Update Operation

Updating a document involves fetching it, modifying the fields, and saving it back to the collection.

import org.springframework.web.bind.annotation.PutMapping;

@RestController
@RequestMapping("/api/users")
public class UserController {

    // (previous code)

    @PutMapping("/{id}")
    public User updateUser(@PathVariable String id, @RequestBody User updatedUser) {
        User existingUser = userRepository.findById(id).orElse(null);
        if (existingUser != null) {
            existingUser.setName(updatedUser.getName());
            existingUser.setEmail(updatedUser.getEmail());
            // update other fields as needed
            return userRepository.save(existingUser);
        }
        return null; // handle not found case
    }
}

In the above example, @PutMapping("/{id}") handles HTTP PUT requests for updating a user by their ID.

Delete Operation

Deleting a document is straightforward with Spring Data MongoDB.

import org.springframework.web.bind.annotation.DeleteMapping;

@RestController
@RequestMapping("/api/users")
public class UserController {

    // (previous code)

    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable String id) {
        userRepository.deleteById(id);
    }
}

The @DeleteMapping("/{id}") annotation maps the endpoint to handle HTTP DELETE requests for deleting a user by their ID.

Best Practices

Now that we’ve covered the basic CRUD operations, let’s discuss some best practices for working with MongoDB in a Spring Boot application.

Indexing

Indexing is crucial for improving query performance. Identify fields used in frequently queried operations and create indexes for them. In Spring Data MongoDB, you can use the @Indexed annotation on entity fields.

import org.springframework.data.mongodb.core.index.Indexed;

public class User {
    // other fields

    @Indexed(unique = true)
    private String email;

    // getters and setters
}

Exception Handling

Handle exceptions gracefully to provide meaningful responses to clients. For instance, handle NoSuchElementException when an entity is not found.

import java.util.NoSuchElementException;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(NoSuchElementException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ResponseEntity<String> handleNoSuchElementException(NoSuchElementException e) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
    }
}

Use DTOs (Data Transfer Objects)

When interacting with clients, consider using Data Transfer Objects (DTOs) to control the data exposed by your API. This helps in preventing over-fetching or under-fetching of data.

public class UserDTO {

    private String id;
    private String name;

    // getters and setters
}

Asynchronous Operations

Consider using asynchronous operations, especially for long-running tasks, to improve the overall responsiveness of your application. Use @Async with methods that can be executed asynchronously.

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Async
    public CompletableFuture<User> getUserByIdAsync(String id) {
        // fetch user from MongoDB
        return CompletableFuture.completedFuture(user);
    }
}

Test Driven Development (TDD)

Embrace Test Driven Development (TDD) to ensure the reliability and correctness of your code. Write unit tests for each CRUD operation.

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

@SpringBootTest
public class UserControllerTests {

    @Autowired
    private UserController userController;

    @Test
    public void testCreateUser() {
        // implement test case
        assertEquals(expected, actual);
    }

    // other test methods
}

In this BitsToGigs post, we explored MongoDB CRUD operations in a Spring Boot application. We covered the basics of setting up a Spring Boot project with MongoDB integration and provided examples of Create, Read, Update, and Delete operations. Additionally, we discussed best practices such as indexing, exception handling, using DTOs, asynchronous operations, and Test Driven Development. By following these best practices, you can build efficient and reliable MongoDB-backed Spring Boot applications.

In the last BitsToGigs post we had discussed @ControllerAdvice annotation.

Happy Learning!

Subscribe to the BitsToGigs Newsletter

What's your reaction?

Excited
0
Happy
0
In Love
0
Not Sure
0
Silly
0

You may also like

More in:Java

Leave a reply

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