You are here
Home > MongoDB >

Spring Boot MongoDB CRUD Example

Spring Boot MongoDB CRUD ExampleIn continuation to MongoDB setup and how to work with Spring Boot in MongoDB, now in this article we will learn the most important DB operations. If we are in Software development world, we should at least know ‘How to write CRUD operation on the database front’. Needless to say, how much importance these operations have. If you are developing any web application in any programming language, you can’t escape from these operations. CRUD is nothing but an abbreviation to Create, Read, Update and Delete. Moreover, development of CRUD operations is expected from all developers. We will learn ‘Spring Boot MongoDB CRUD Example’ in this article.

In order to implement CRUD Operations in Spring Boot with MongoDB, we will make use of MongoRepository interface to communicate with the database. Let’s discuss our topic ‘Spring Boot MongoDB CRUD Example’.

Software/Technologies Used in the Examples

Before talking about Spring Boot MongoDB CRUD Example, let’s summarize the software/technologies that we are going to use.

1) MongoDB – 3.8.2
2) IDE – STS : 4.7.1.RELEASE
3) JDK – 1.8 or later(Extremely tested on JDK 15)
4) Spring Data MongoDB : 3.0.5.RELEASE
5) Spring Boot – 2.3.5.RELEASE
6) Spring Framework – 5.2.10.RELEASE
7) Maven – 3.8.1
8) Lombok : 1.18.16

Pre-requisite

In order to test the Spring Boot MongoDB CRUD Example, you must have MongoDB installed in your system. If not, please visit our article on how to install MongoDB in your system. Here, you will find step by step tutorial to download & install MongoDB including some required commands to operate on it.

What is MongoRepository<T, ID> ?

MongoRepository<T, ID> is an important interface which will help you to write CRUD operations easily. For example, in our case we will extend our custom Repository interface from this interface. However, It is just like JpaRepositry<T, ID> that we use to write CRUD operations in case of SQL databases. Both of them extends PagingAndSortingRepository<T, ID> and QueryByExampleExecutor<T> interfaces. We can go through the primary diagram of this article in order to understand complete hierarchy of MongoRepository<T, ID> & JpaRepositry<T, ID> as well.

The MongoRepository interface is a part of the Spring Data MongoDB module, which integrates MongoDB with Spring Data, a broader part of the Spring Framework that provides support for data access across various database types.

Spring Boot MongoDB CRUD Example

When we create an interface that extends MongoRepository, we can automatically gain access to a wide range of methods for interacting with MongoDB database and also helps in eleminating boilerplate code. This includes standard operations such as saving, finding, deleting, and updating documents within a MongoDB collection.

Write Basic Codes to Develop Spring Boot MongoDB CRUD Example

In order to develop and test Spring Boot MongoDB CRUD Example, we will write some basic codes that will be applicable to each operation.

Step#1 : Create a Spring Boot Project using STS(Spring Tool Suite)

Here, we will use STS(Spring Tool Suite) to create our Spring Boot Project. If you are new to Spring Boot, visit Internal Link to create a sample project in spring boot using STS. While creating a project in STS, add starters ‘Spring Data MongoDB’, and ‘Lombok’ in order to get the features of MongoDB. Furthermore, if you are new to ‘Lombok’, kindly visit ‘How to configure Lombok‘ and to know all about it in detail.

Step#2 : Update application.properties

Update application.properties as below.

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

If you are using MongoDB in authentication mode, include the username and password of it accordingly.

Step#3 : Create entity class

Here we will use Book as an entity to illustrate the examples. Hence create a Book.java class as below.

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;

@Data
@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor
@Document              // Maps Entity class objects to JSON formatted Documents
public class Book {

          @Id                 // making this variable as ID, will be auto-generated by MongoDB
          private String id;

          @NonNull
          private Integer bookId;
          @NonNull
          private String bookName;
          @NonNull
          private String bookAuthor;
          @NonNull
          private Double bookCost;
}

Step#4 : Create a Repository interface

In order to support DB operations, we will create one Repository interface. As per convention, we name it BookRepository.java which will extend MongoRepository<Book, Integer> as below.

import org.springframework.data.mongodb.repository.MongoRepository;
import com.dev.springboot.mongodb.entity.Book;

public interface BookRepository extends MongoRepository<Book, String> {

}

Note : We will create a Runner class to write and test for each operation in further steps. Moreover, we will name the Runner class prefixed with the operation name to make it understand easier.

save(), saveAll(), insert() Operations Example using Spring Boot & MongoDB

import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import com.dev.springboot.mongodb.entity.Book;
import com.dev.springboot.mongodb.repo.BookRepository;

@Component
public class saveOperationRunner implements CommandLineRunner {

       @Autowired
       private BookRepository bookRepo;

       @Override
       public void run(String... args) throws Exception {

        // saveAll() operation : saveAll() inserts more than one records at a time

             bookRepo.saveAll(Arrays.asList(
                              new Book(501, "Core Java", "Kathy Sierra", 1065.5),
                              new Book(502, "Spring in Action", "Craig Walls", 940.75),
                              new Book(503, "Hibernate in Action", "Gavin King", 889.25),
                              new Book(504, "Practical MongoDB", "Shakuntala Gupta", 785.0)
             ));             

       // save() operation : Updating ID(PK) manually (allowed) : It will create one new record

           Book book = bookRepo.save(new Book("ISBN10:1484240251", 504,"Practical MongoDB", "Shakuntala Gupta", 785.0));  // insert
     
      // save() operation : save() also updates record based on the PK

           bookRepo.save(new Book("ISBN10:1484240251", 505,"Practical MongoDB", "Shakuntala Gupta", 728.0));  // update
           bookRepo.save(new Book(book.getId(), 505,"Practical MongoDB", "Navin Sabharwal", 798.0));  // update
           
      // insert() operation : This method will also insert one new record

           bookRepo.insert(new Book(506,"Java Design Patterns", "Kathy Sierra", 924.0)); // insert

           System.out.println("All Data saved into MongoDB");
           }
}

Note : ‘save(Object) : object’  method is used to perform both insert and update(based on ID) and returns the same object with ID effected/updated. However, we can also provide ID either manually or use some code for ID generation like at application side, we can pass the ID (String-Hexa Decimal number).

findAll() Operation Example using Spring Boot & MongoDB

In order to test findAll() functionality, Let’s find all values saved into the DB in the previous example.

import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import com.dev.springboot.mongodb.entity.Book;
import com.dev.springboot.mongodb.repo.BookRepository;

@Component
public class findOperationRunner implements CommandLineRunner {

 @Autowired
 private BookRepository bookRepo;

 @Override
 public void run(String... args) throws Exception {

      // findAll() : It will retireve all records saved into DB 
          List<Book> bookList = bookRepo.findAll();
          bookList.forEach(System.out::println);     // Printing all saved books
          }
}

Output

Book(id=60827aa043ffdb1a24cd24fa, bookId=501, bookName=Core Java, bookAuthor=Kathy Sierra, bookCost=1065.5)
Book(id=60827aa043ffdb1a24cd24fb, bookId=502, bookName=Spring in Action, bookAuthor=Craig Walls, bookCost=940.75)
Book(id=60827aa043ffdb1a24cd24fc, bookId=503, bookName=Hibernate in Action, bookAuthor=Gavin King, bookCost=889.25)
Book(id=60827aa043ffdb1a24cd24fd, bookId=504, bookName=Practical MongoDB, bookAuthor=Shakuntala Gupta, bookCost=785.0)
Book(id=ISBN10:1484240251, bookId=505, bookName=Practical MongoDB, bookAuthor=Navin Sabharwal, bookCost=798.0)
Book(id=6082dc74562e1d17d587985e, bookId=506, bookName=Java Design Patterns, bookAuthor=Kathy Sierra, bookCost=924.0)

As from the output above, it is clear that the first four books are getting auto-generated id value. However, the last book has a manually inserted id and other field’s value in the last book has also been updated accordingly. 

findById() Operation Example using Spring Boot & MongoDB

Optional<Book> opt= bookRepo.findById("ISBN10:1484240251");
if(opt.isPresent()) {
Book b1 = opt.get();
System.out.println("Here is the book details : " +b1);
} else {
System.out.println("Given Id not found");
}

delete() Operation Example using Spring Boot & MongoDB

Generally, we use two methods to delete records from the DB: deleteById( ) and deleteAll( )

bookRepo.deleteById("ISBN10:1484240251");    // Delete Book of a particular Id 

bookRepo.deleteAll();               // Deleting all books

REST Controller Example

Let’s create all operations in the Controller as below:

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.dev.springboot.model.Book;
import com.dev.springboot.repo.BookRepository;

@RestController
@RequestMapping("/api")
public class BookController {

    @Autowired
    BookRepository bookRepo;

    @GetMapping("/books")
    public ResponseEntity<List<Book>> getAllBooks() {

        try {
         List<Book> books = new ArrayList<Book>();
           if (books.isEmpty()) {
               return new ResponseEntity<>(HttpStatus.NO_CONTENT);
           } else
             bookRepo.findAll().forEach(books::add);
               return new ResponseEntity<>(books, HttpStatus.OK);
           } catch (Exception e) {
              return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @GetMapping("/books/{id}")
    public ResponseEntity<Book> getBookById(@PathVariable("id") Integer id) {

        Optional<Book> book = bookRepo.findById(id);

        if (book.isPresent()) {
          return new ResponseEntity<>(book.get(), HttpStatus.OK);
        } else {
          return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }

    @PostMapping("/books")
    public ResponseEntity<String> saveBook(@RequestBody Book book) {

        try {
           bookRepo.save(book);
           return new ResponseEntity<String>("Book saved", HttpStatus.CREATED);
        } catch (Exception e) {
           return new ResponseEntity<>("Unable to save book", HttpStatus.INTERNAL_SERVER_ERROR);
        }

    }

    @PutMapping("/books/{id}")
    public ResponseEntity<Book> updateBook(@PathVariable("id") Integer id, @RequestBody Book book) {

        Optional<Book> opt = bookRepo.getBookById(id);

        if (opt.isPresent()) {
          Book book1 = opt.get();
          book1.setAuthor(book.getAuthor());
          book1.setName(book.getName());
          book1.setCost(book.getCost());
          return new ResponseEntity<>(bookRepo.save(book1), HttpStatus.OK);
        } else {
           return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }

    @DeleteMapping("/books/{id}")
    public ResponseEntity<HttpStatus> deleteBook(@PathVariable("id") Integer id) {

        try {
          bookRepo.deleteById(id);
          return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        } catch (Exception e) {
           return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @DeleteMapping("/books")
    public ResponseEntity<HttpStatus> deleteAllBooks() {

        try {
          bookRepo.deleteAll();
          return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        } catch (Exception e) {
           return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}

This is all about Spring Boot MongoDB CRUD Example. If you want to learn ‘How to write CRUD operation in Spring WebFlux using Spring Data Reactive Mongo DB’, kindly visit our article ‘Reactive CRUD Example using Spring WebFlux and MongoDB‘. Furthermore, if you want to learn about MongoDB specific CRUD operations without using Spring Boot, kindly visit official website. Additionally, If you want to learn more on NoSQL databases and have a good understanding of them, kindly visit a separate article on ‘All About NoSQL Databases‘.

Links to Other tutorials on MongoDB with Spring Boot

Below are the links to learn MongoDB deeply with Spring Boot.

MongoDB Basics & How to work with Spring Boot 
Spring Boot MongoDB @Query Examples
MongoTemplate Spring Boot Examples including CRUD

Leave a Reply


Top