opencodez

Simple and Easy way to connect MongoDB Atlas with Spring Boot

In this brief article, we will see how we can use MongoDB Atlas with Spring Boot. MongoDB Atlas is Database as a Service. With database available on the cloud you can scale it as and when you need.

Software used

POM

xdependenciesx
	xdependencyx
		xgroupIdxorg.springframework.bootx/groupIdx
		xartifactIdxspring-boot-starter-data-mongodbx/artifactIdx
	x/dependencyx

	xdependencyx
		xgroupIdxorg.projectlombokx/groupIdx
		xartifactIdxlombokx/artifactIdx
		xoptionalxtruex/optionalx
	x/dependencyx
	xdependencyx
		xgroupIdxorg.springframework.bootx/groupIdx
		xartifactIdxspring-boot-starter-testx/artifactIdx
		xscopextestx/scopex
	x/dependencyx
x/dependenciesx

Spring has always made development easy. For our POC as well we are using pre-built dependencies for MongoDB. Along with spring-boot-starter-data-mongodb we will use Project Lombok for easy POJO management.

MongoDB Atlas URL

To connect to MongoDB on the cloud you need to have the exact URL of your database with user and password. You can get this URL in your Atlas account as shown below

For our example, we have added below in our application.properties

spring.data.mongodb.uri=mongodb+srv://nodeuser:nodepwd@opencodez-pzgjy.gcp.mongodb.net/test?retryWrites=true
spring.data.mongodb.database=test

You may have to change IP whitelisting as well because by default MongoDB Atlas wonxt allow connecting from any IP address.

Define Collection

MongoDB is a NoSQL database, so it uses collections concept instead of tables. We will define our collection java mapping as below

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

import lombok.Data;

@Data
@Document(collection = "users")
public class Users {

	@Id
	private String id;
	private String name;
	private String address;
	private Double salary;
	
	public Users(String name, String address, Double salary) {
		this.name = name;
		this.address = address;
		this.salary = salary;
	}
}

The java class also has a convenience constructor defined.

Define Repository

As we are using Spring Data for MongoDB, defining a repository is as easy as adding an interface like below

public interface UserRepository extends MongoRepositoryxUsers, Stringx {
}

Thatxs it, with above interface you will get access to all the CRUD operations around the MongoDB collection. If you need you can add some methods for your convenience as well

public interface UserRepository extends MongoRepositoryxUsers, Stringx {
	
    Users findFirstByName(String name);
	
    @Query("{address:'?0'}")
    ListxUsersx findCustomByAddress(String address);

    @Query("{address : { $regex: ?0 } }")
    ListxUsersx findCustomByRegExAddress(String domain);

}

You can see that the interface supports methods based on field names as well as it supports the query based on JSON.

Custom MongoDB Repository

Apart from the standard Spring Data Repository, you can define your own as well. In that case, you can use MongoTemplate. A sample is also included below for reference

public interface CustomRepository {
	long updateUser(String address, Double salary);
}

Implementation

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.Component;

import com.mongodb.client.result.UpdateResult;
import com.opencodez.domain.Users;

@Component
public class CustomRepositoryImpl implements CustomRepository {

	@Autowired
	MongoTemplate mongoTemplate;

	@Override
	public long updateUser(String address, Double salary) {
		
		Query query = new Query(Criteria.where("address").is(address));
		Update update = new Update();
		update.set("salary", salary);
		
		UpdateResult result = mongoTemplate.updateFirst(query, update, Users.class);

		if (result != null)
			return result.getModifiedCount();
		else
			return 0;
	}

}

The implementation is self-explanatory and I hope does not require any details.

Running the example

As we are using Spring Boot, we will add a command line runner with all the utility methods in it.

@SpringBootApplication
public class MongoBootApplication implements CommandLineRunner {

	@Autowired
	UserRepository repository;
	
	@Autowired
	CustomRepository crepo;
	
	public static void main(String[] args) {
		SpringApplication.run(MongoBootApplication.class, args);
	}

	@Override
	public void run(String... args) throws Exception {
		deleteAll();
		addSampleData();
		listAll();
		findFirst();
		findByRegex();
	}
	
	public void deleteAll() {
		System.out.println("Deleting all records..");
		repository.deleteAll();
	}
	
	public void addSampleData() {
		System.out.println("Adding sample data");
		repository.save(new Users("Jack Bauer", "New York", 11111d));
		repository.save(new Users("Harvey Spectre", "London", 22222d));
		repository.save(new Users("Mike Ross", "New Jersey", 333333d));
		repository.save(new Users("Louise Litt", "Kathmandu", 44444d));
	}
	
	public void listAll() {
		System.out.println("Listing sample data");
		repository.findAll().forEach(u -x System.out.println(u));
	}
	
	public void findFirst() {
		System.out.println("Finding first by Name");
		Users u = repository.findFirstByName("Louise Litt");
		System.out.println(u);
	}
	
	public void findByRegex() {
		System.out.println("Finding by Regex - All with address starting with ^New");
		repository.findCustomByRegExAddress("^New").forEach(u -x System.out.println(u));
	}
}

The output

Deleting all records..
2018-10-26 21:39:40.701  INFO 32780 --- [           main] org.mongodb.driver.connection            : Opened connection [connectionId{localValue:4, serverValue:1761}] to opencodez-shard-00-01-pzgjy.gcp.mongodb.net:27017
Adding sample data
Listing sample data
Users(id=5bd33c44769b73800cc40c98, name=Jack Bauer, address=New York, salary=11111.0)
Users(id=5bd33c44769b73800cc40c99, name=Harvey Spectre, address=London, salary=22222.0)
Users(id=5bd33c45769b73800cc40c9a, name=Mike Ross, address=New Jersey, salary=333333.0)
Users(id=5bd33c45769b73800cc40c9b, name=Louise Litt, address=Kathmandu, salary=44444.0)
Finding first by Name
Users(id=5bd33c45769b73800cc40c9b, name=Louise Litt, address=Kathmandu, salary=44444.0)
Finding by Regex - All with address starting with ^New
Users(id=5bd33c44769b73800cc40c98, name=Jack Bauer, address=New York, salary=11111.0)
Users(id=5bd33c45769b73800cc40c9a, name=Mike Ross, address=New Jersey, salary=333333.0)

Also below is the actual data from our MongoDB instance.

Conclusion

In this article we have seen, how easy it is to connect to a NoSQL MongoDB Cloud instance with Spring Boot. Please feel free to comment or ask a question or two.

You can find the complete source code at our GIT repository.

Download Code