Amazon DocumentDB (compatible with MongoDB) is a scalable, highly durable, and fully managed database service for operating mission-critical MongoDB workloads. On Amazon DocumentDB, you can use the same MongoDB application code, drivers, and tools to run, manage, and scale workloads without having to worry about managing the underlying infrastructure.
Spring Boot provides an easy and fast way to build production-grade applications based on the Spring framework. In order to do this, Spring Boot prepackages auto-configuration modules for most of the libraries commonly used with the Spring Framework. In short, open source Spring Boot follows conventions about configuration, adding auto-configuration capabilities on top of the Spring framework.
In this post, you'll explore the basics of integrating a Spring Boot application with Amazon DocumentDB using the Spring Data MongoDB API. You can also create sample data models and repository classes for performing database operations.
Solution overview
The configuration of Spring Boot and Amazon DocumentDB is relatively simple, involving only a few configuration steps.
Spring Boot allows applications to interact with Amazon DocumentDB using the MongoTemplate class and the MongoRepository interface. MongoTemplate follows the standard template pattern in Spring and provides a ready-made basic API for the underlying persistence engine. MongoTemplate provides out-of-the-box APIs for operations such as aggregation, streaming, updates, and custom queries. MongoRepository follows a Spring Data-centric approach, providing a more flexible and simpler API based on the well-known Create, Read, Update, and Delete (CRUD, Create, Read, Update, and Delete) access patterns in all Spring Data projects operate.
For both options, you first define dependencies for your Maven project in pom.xml.
This post focuses on how to use MongoRepository to interact with Amazon DocumentDB.
prerequisites
You need to meet the following prerequisites:
Amazon DocumentDB cluster – This article starts with an existing Amazon DocumentDB cluster that you will integrate with your Spring Boot application. If you don't already have an Amazon DocumentDB cluster, see Get Started with Amazon DocumentDB (Getting Started with Amazon DocumentDB) to create a new cluster (https://docs.aws.amazon.com/documentdb/latest/developerguide/get-started-guide.html ).
Integrated Development Environment (IDE) – For example, Eclipse or Amazon Cloud9. This demo uses Amazon Cloud9, a cloud-based IDE that lets you write, run, and debug code using just a browser. It includes code editors, debuggers, and terminals. Enable Enhanced support for Java development (https://docs.aws.amazon.com/cloud9/latest/user-guide/enhanced-java.html) to improve your development experience when using Java.
Java 17 – For information on installing or upgrading Java in Amazon Cloud9, see the Amazon Corretto 17 Installation Instructions (https://docs.aws.amazon.com/corretto/latest/corretto-17- ug/amazon-linux-install.html)
Maven – See Setting Up Maven to Install Maven in Amazon Cloud9 (https://docs.aws.amazon.com/cloud9/latest/user-guide/sample-java.html#sample-java-sdk-maven)
Spring Initializr
Charges associated with Amazon DocumentDB and Amazon Cloud9 resources may accrue to your account. You can use the Amazon Web Services Pricing Calculator to estimate this cost (https://calculator.aws/).
Using Spring Initializr
Create a Spring Boot application
Using the following steps, create a new Spring Boot application project that supports Spring Data MongoDB. As an alternative, you can use the spring-boot-docdb-sample application from the GitHub repository. (https://github.com/aws-samples/amazon-documentdb-samples/tree/master/blogs/docdb-springboot)
1. Browse to https://start.spring.io/.
2. Specify the following options:
Select Maven project (Maven project), and Language (language) is Java .
Choose version 3.0.0 of Spring Boot.
Specify a group and artifact name for the application.
Specifies Java version 17.
Select ADD DEPENDENCIES (Add dependencies), then search for and select Spring Data MongoDB . You can use the Spring Data MongoDB dependency to interact with an Amazon DocumentDB cluster from this application.
3. Choose GENERATE to generate a Spring Boot project that contains all the files needed for bootstrapping.
4. Download the ZIP file to a path on your local computer and extract the file.
If you are using the Amazon Cloud9 IDE, upload the ZIP file to the Amazon Cloud9 environment and unzip the file.
Verify Maven dependencies
Locate the pom.xml file in the application's directory, and verify that the Spring Data MongoDB dependency has been added as follows:
XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
Swipe left to see more
Define the data model
To store and retrieve data in an Amazon DocumentDB database, we first create a POJO model or entity class. This entity represents a collection in Amazon DocumentDB and uses annotations to define the collection name, properties, keys, and other aspects.
In this example, you create a collection of products and a corresponding model object that stores the details of the products in a catalog database. You create a product model with six attributes: id , name , sku , description , inventory , and category .
Amazon DocumentDB stores data in collections. By default, Spring Data maps a product class or model to a collection named product. If you want to change the name of the collection, you can use Spring Data MongoDB's @Document annotation on the class. In the following example, we use @Document(collection = "products") to specify the collection name as products .
You can specify the document's primary key _id with the @Id annotation. If you don't specify anything, Amazon DocumentDB will generate the _id field when creating the document. Other attributes are not commented. This assumes that they map to fields with the same names as the properties themselves. In the project's directory, create a Product.java file with the following content:
Java
@Id
private String id;
/**
* 设置对应于 products 集合中字段的数据成员
*/
private String name;
private String sku;
private String description;
private int inventory;
private String category;
/**
* @param id
* @param name
* @param sku
* @param description
* @param inventory
* @param category
*/
public Product(String name, String sku, String description, int inventory, String category) {
this.name = name;
this.sku = sku;
this.description = description;
this.inventory = inventory;
this.category = category;
}
}
Swipe left to see more
Add getter and setter methods for each property. You can generate getter and setter methods using IDE-specific shortcuts. For example, right-click the code editor pane, select Refactoring (refactoring), and then select Generate Getter and Setter in Cloud9 (Generate Getter and Setter in Cloud9).
Also, it is recommended to override the toString method to output the object, for example, right-click on the code editor pane, select Refactoring , and then select Generate toString() in Cloud9 (Generate toString() in Cloud9)
Connect with TLS enabled
To connect to a TLS-enabled Amazon DocumentDB cluster from a Java-based Spring Boot application, your program must use a Certificate Authority (CA, Certificate Authority) file provided by Amazon Web Services to authenticate the connection. To use an Amazon RDS CA certificate:
1. Create a temporary certs folder under the tmp folder. You can create folders for storing certificates according to your organization's security policy. In this article, create a certs folder under tmp:
Bash
mkdir /tmp/certs/
2. Run the following command to create a trust store using the CA certificate contained in the file. Make sure to update <truststorePassword>. The following shell script example imports a certificate bundle into a trust store on a Linux operating system. For other options, see Connecting with TLS Enabled (https://docs.aws.amazon.com/documentdb/latest/developerguide/connect_programmatically.html#connect_programmatically-tls_enabled).
Bash
mydir=/tmp/certs
truststore=${mydir}/rds-truststore.jks
storepassword=<truststorePassword>
curl -sS "https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem" > ${mydir}/rds-combined-ca-bundle.pem
awk 'split_after == 1 {n++;split_after=0} /-----END CERTIFICATE-----/ {split_after=1}{print > "rds-ca-" n ".pem"}' < ${mydir}/rds-combined-ca-bundle.pem
for CERT in rds-ca-*; do
alias=$(openssl x509 -noout -text -in $CERT | perl -ne 'next unless /Subject:/; s/.*(CN=|CN = )//; print')
echo "Importing $alias"
keytool -import -file ${CERT} -alias "${alias}" -storepass ${storepassword} -keystore ${truststore} -noprompt
rm $CERT
done
rm ${mydir}/rds-combined-ca-bundle.pem
echo "Trust store content is: "
keytool -list -v -keystore "$truststore" -storepass ${storepassword} | grep Alias | cut -d " " -f3- | while read alias
do
expiry=`keytool -list -v -keystore "$truststore" -storepass ${storepassword} -alias "${alias}" | grep Valid | perl -ne 'if(/until: (.*?)\n/) { print "$1\n"; }'`
echo " Certificate ${alias} expires in '$expiry'"
done
Swipe left to see more
Database and connection configuration
Two configuration files are required to set up the connection details and SSL trust store. First, define your Amazon DocumentDB connection parameters such as database, URI or host, port, username, and password in application.properties. Then set the keystore in the configuration class.
Configure the Spring Boot application properties file
To connect a Spring Boot application to Amazon DocumentDB, we need to define the database configuration in the application.properties file. You need to configure properties such as database URI, database name or hostname, username, password, and other connection-related properties. To connect to an Amazon DocumentDB cluster, you need to specify the connection URI string in the application.properties file located in the src/main/resources folder.
To retrieve your Amazon DocumentDB cluster endpoint and configure application.properties , complete the following steps:
1. In the navigation pane of the Amazon DocumentDB console, choose Clusters .
2. Find your cluster and choose the regional cluster identifier.
3. On the Connectivity & security tab, copy the link used by the application.
Command to connect to the cluster.
4. Remove &ssl_ca_certs=rds-combined-ca-bundle.pem from the copied connection string since you already imported the CA file provided by Amazon Web Technologies into the trust store.
5. Add the connection URI to the application.properties file located in your project's src/main/resources folder. The connection URI key is spring.data.mongodb.uri . Make sure the copied connection string is in the following format:
spring.data.mongodb.uri=mongodb://<用户名>:<密码>@<集群端点>: 27017/?ssl=true&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false
Swipe left to see more
Alternatively, you can provide connection details individually, including hostname, port, username, and password, and corresponding property keys, such as spring.data.mongodb.host or spring.data.mongodb.port . For a complete list of available Spring Boot parameter configuration options, see Data Properties under Common Application Properties (https://docs.spring.io/spring-boot/docs/current/ reference/html/application-properties.html#appendix.application-properties.data).
6. Optionally, specify the database name in the application.properties file:
spring.data.mongodb.database=catalog
Create a configuration class and set up the keystore
Now that the property configuration is complete, you need to define a configuration class to set keystore properties in order to establish a secure connection.
To use the keystore in your application, set the following system property in your configuration class:
javax.net.ssl.trustStore: <truststore>
javax.net.ssl.trustStorePassword: <truststorePassword>
Swipe left to see more
See the example configuration class below. Mark the class as a configuration class with the @Configuration annotation. Classes annotated with @Configuration are used by the Spring container as a source of bean definitions.
Java
@Bean
public MongoClientSettings mongoClientSettings() {
setSslProperties();
return MongoClientSettings.builder()
.applyToSslSettings(builder -> builder.enabled(true))
.build();
}
private static void setSslProperties() {
System.setProperty("javax.net.ssl.trustStore", KEY_STORE_TYPE);
System.setProperty("javax.net.ssl.trustStorePassword",
DEFAULT_KEY_STORE_PASSWORD);
}
@Bean
public MongoPropertiesClientSettingsBuilderCustomizer mongoPropertiesCustomizer(final MongoProperties properties) {
return new MongoPropertiesClientSettingsBuilderCustomizer(properties);
}
}
Swipe left to see more
That's all for Amazon DocumentDB configuration in Spring Boot Now, you can start defining interface-based repository classes by extending MongoRepository .
Configure the repository interface
Now you can use MongoRepository to access the data in the database. MongoRepository provides common functionality such as Create, Read, Update, and Delete (CRUD, Create, Read, Update, and Delete) operations. It acts as a link between the model and the database. It gets the domain class (Product) to manage, and gets the ID type of the domain class as a type parameter. There are several methods you can write that let the repository generate the query for you.
Create a repository interface that queries Product documents as follows:
Java
public interface ProductRepository extends MongoRepository<Product, String> {
}
Swipe left to see more
ProductRepository extends the MongoRepository interface. This interface contains many operations, including standard CRUD operations. You'll define other custom actions in the next section.
Define service class
The service classes make use of the Spring Data repository interface. We define it by referencing the repository you created in the previous step:
Java
@Service
public class ProductService {
@Autowired
private ProductRepository productRepo;
}
Swipe left to see more
You'll build on this class by adding additional methods in the next section, which also presents a CRUD example.
Use CrudRepository
When using a MongoRepository that extends CrudRepository , your repository can access basic functionality, including save , count , findAll , and delete methods, from classes that implement the CrudRepository interface. Your ProductRepository interface extends MongoRepository and has access to all basic CRUD operations.
Let's explore and test these operations one by one.
save or create
First, you add some documents to the collection using the save method. The save method takes a Product object as input and saves the product document to an Amazon DocumentDB collection. Add the following code snippet to your service class:
Java
public void saveProducts() {
productRepo.save(new Product("RayBan Sunglass Pro", "1590234","RayBan Sunglasses for professional sports people", 100, "fashion"));
productRepo.save(new Product("GUCCI Handbag", "3451290", "Fashion Hand bags for all ages", 75, "fashion"));
productRepo.save(new Product("Round hat", "8976045", "", 200, "fashion"));
productRepo.save(new Product("Polo shirt", "6497023", "Cool shirts for hot summer", 25, "cloth"));
productRepo.save(new Product("Swim shorts", "8245352", "Designer swim shorts for athletes", 200, "cloth"));
productRepo.save(new Product("Running shoes", "3243662", "Shoes for work out and trekking", 20, "footware"));
System.out.println(" Save complete ");
}
Swipe left to see more
count
In the next example, if there are no methods in the repository, the count() method in the service class is called to count the documents in the collection.
Java
public long getCount() {
long count = productRepo.count();
System.out.println(" Total number of products : "+count);
return count;
}
Swipe left to see more
read
In this example, you perform three different read operations. You can extract products by name or SKU, and find product listings based on category.
You added three simple methods to your repository ( ProductRepository ). The first method findProductByName queries the collection based on the name attribute. Query filters are defined using the annotation @Query , in this case @Query("{name:'?0'}") . The second method findProductBySKU queries the collection based on the sku attribute and outputs only the name and inventory attributes in the query response. The third method findAll retrieves all documents of a specific category. See the code below:
Java
public interface ProductRepository extends MongoRepository<Product, String> {
@Query("{name:'?0'}")
Product findProductByName(String name);
@Query(value="{sku:'?0'}", fields="{'name' : 1, 'inventory' : 1}")
Product findProductBySKU (String sku);
@Query("{category:'?0'}")
List<Product> findAllByCategory(String category);
}
Swipe left to see more
You can call these three methods in the service class from the repository to find documents by name, SKU, and category.
Java
public Product getProductByName(String name) {
System.out.println(" Getting product by name : " + name);
Product product = productRepo.findProductByName(name);
System.out.println(product);
return product;
}
public Product getProductBySKU(String sku) {
System.out.println(" Getting product by SKU : " + sku);
Product product = productRepo.findProductBySKU(sku);
System.out.println(product);
return product;
}
public List<Product> findAllProductsByCategory(String category) {
List<Product> productList = productRepo.findAllByCategory(category);
productList.forEach(product -> System.out.println(product));
return productList;
}
Swipe left to see more
renew
You can use the save method to update an existing document by passing the updated entity object. In this example, you query for existing products by SKU and increase inventory by 10. Add the following method to your service:
Java
public void updateInventory(String sku) {
Product product = getProductBySKU(sku);
System.out.println(" Updating Inventory for product by sku: " + sku);
product.setInventory(product.getInventory()+10);
Product updatedProd = productRepo.save(product);
}
Swipe left to see more
delete
In this example, you will create two delete operations. First, you delete a product by ID; in the second approach, you delete all documents (products) in the collection. Add the following method to your service class:
Java
public void deleteProduct(String id) {
productRepo.deleteById(id);
System.out.println("Product with id " + id + " deleted");
}
public void deleteAll() {
productRepo.deleteAll();
System.out.println("All Products deleted.");
}
Swipe left to see more
Build a Spring Boot application
A default Spring Boot application is already created by Spring Initializr in a root package (eg com.example.documentdb ). Open the default application in the IDE:
Java
@SpringBootApplication
public class DocumentdbApplication {
public static void main(String[] args) {
SpringApplication.run(DocumentdbApplication.class, args);
}
}
Swipe left to see more
The CommandLineRunner interface indicates that a bean should be run when it is included in a SpringApplication so that the output can be viewed on the console. Implement the CommandLineRunner interface and provide an implant for the run method. We define a reference to your service using the @Autowired annotation. Spring uses the @SpringBootApplication annotation to initialize the application context:
Java
@Override
public void run(String... args) throws Exception {
System.out.printf("%n Insert few products : %n");
prodService.saveProducts();
System.out.printf("%n Count all products : %n");
prodService.getCount();
System.out.printf("%n Get product by name : %n");
prodService.getProductByName("GUCCI Handbag");
System.out.printf("%n Get product by sku : %n");
prodService.getProductBySKU("8976045");
System.out.printf("%n Get all products by category : %n");
prodService.findAllProductsByCategory("fashion");
System.out.printf("%n Update Inventory for Product by sku : %n");
prodService.updateInventory("3451290");
System.out.printf("%n Delete product id %n");
prodService.deleteProduct("639a0046efe46b7343dd5004");
System.out.printf("%n Deleting all products/documents %n");
prodService.deleteAll();
}
}
Swipe left to see more
Run and test your application
Run the Spring Boot application with the following Maven command:
Bash
mvn spring-boot:run
The following screenshot is a sample output of a Spring Boot application.
You did it! You have successfully connected to Amazon DocumentDB from your Spring Boot application.
Summarize
In this article, you learned how to integrate Amazon DocumentDB with a Spring Boot application through a simple application that uses Spring Data MongoDB to save and fetch objects to and from the database, all without writing Concrete repository implementation with simple configuration.
The samples used in this post are available as a sample project on GitHub (https://github.com/aws-samples/amazon-documentdb-samples/tree/master/blogs/docdb-springboot).
Original URL:
https://aws.amazon.com/cn/blogs/database/integrate-your-spring-boot-application-with-amazon-documentdb/
The author of this article
Gururaj S Bayari
Senior DocumentDB Expert Solution Architect at Amazon Cloud Technology. He enjoys helping customers adopt Amazon's dedicated databases. He helps clients design, evaluate and optimize Internet-scale high-performance workloads using NoSQL and/or relational databases.
I heard, click the 4 buttons below
You will not encounter bugs!