[Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail)(与 MongoDB 兼容)是一种可扩展、高度持久和完全托管的数据库服务,用于操作任务关键型 MongoDB 工作负载。在 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 上,您可以使用相同的 MongoDB 应用程序代码、驱动程序和工具来运行、管理和扩展工作负载,无需关心管理底层基础设施。
Spring Boot 提供了简单快速的方法,可基于 Spring 框架来构建生产级的应用程序。为了做到这一点,Spring Boot 预先打包自动配置模块,用于通常与 Spring Framework 一起使用的大多数库。简而言之,开源 Spring Boot 遵循有关配置的惯例,在 Spring 框架之上添加了自动配置功能。
在这篇文章中,您将探索使用 Spring Data MongoDB API,将 Spring Boot 应用程序集成到 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 的基础知识。您还可以创建示例数据模型和存储库类用于执行数据库操作。
### **解决方案概览**
Spring Boot 和 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 的配置相对简单,只涉及几个配置步骤。
Spring Boot 允许应用程序使用 `MongoTemplate` 类和 `MongoRepository` 接口,与 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 交互。 `MongoTemplate` 遵循 Spring 中的标准模板模式,为底层持久性引擎提供了现成的基本 API。MongoTemplate 为聚合、流式处理、更新和自定义查询等操作提供了直接可用的 API。MongoRepository 遵循以 Spring Data 为中心的方法,基于所有 Spring Data 项目中广为人知的创建、读取、更新和删除(CRUD,Create, Read, Update, and Delete)访问模式,提供了更灵活、更简单的 API 操作。
对于这两个选项,您首先要在 `pom.xml` 中为 Maven 项目定义依赖项。
这篇文章重点介绍如何使用 `MongoRepository` 与 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 交互。
### **先决条件**
您需要满足以下先决条件:
* **[Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 集群** – 这篇文章首先介绍现有的 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 集群,您要将其与 Spring Boot 应用程序集成。如果您还没有 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 集群,请参阅 Get Started with [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) ([Amazon DocumentDB 入门](https://docs.aws.amazon.com/documentdb/latest/developerguide/get-started-guide.html?trk=cndc-detail)) 以创建新集群。
* **集成式开发环境(IDE)** – 例如,Eclipse 或 Amazon Cloud9。本文在演示中使用了 Amazon Cloud9,这是一款基于云的 IDE,让您只需使用浏览器即可编写、运行和调试代码。其包括代码编辑器、调试程序和终端。启用增强了对 [Java](https://docs.aws.amazon.com/cloud9/latest/user-guide/enhanced-java.html?trk=cndc-detail) 开发的支持,改善您在使用 Java 时的开发体验。
* **Java 17** – 有关在 Amazon Cloud9 中安装或升级 Java 的信息,请参阅 [Amazon Corretto](https://aws.amazon.com/cn/corretto/?trk=cndc-detail) 17 Installation Instructions([Amazon Corretto 17 安装说明](https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/amazon-linux-install.html?trk=cndc-detail))
* **Maven** – 请参阅设置 Maven 以在 Amazon Cloud9 中安装 [Maven](https://docs.aws.amazon.com/cloud9/latest/user-guide/sample-java.html#sample-java-sdk-maven?trk=cndc-detail)
* Spring Initializr
您的账户中可能会产生与 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 和 Amazon Cloud9 资源相关的费用。您可以使用[亚马逊云科技定价计算器](https://calculator.aws/?trk=cndc-detail)来估计此费用。
### **使用 Spring Initializr 创建 Spring Boot 应用程序**
使用以下步骤,创建一个支持 Spring Data MongoDB 的新 Spring Boot 应用程序项目。作为替代方法,您可以使用 GitHub 存储库中的 [`spring-boot-docdb-sample`](https://github.com/aws-samples/amazon-documentdb-samples/tree/master/blogs/docdb-springboot?trk=cndc-detail) 应用程序。
1\. 浏览到 https\://start.spring.io/?trk=cndc-detail。
2\. 指定以下选项:
1. 选择 **Maven project**(Maven 项目),且 **Language**(语言)为 **Java**。
2. 选择 Spring Boot 的版本 3.0.0。
3. 为应用程序指定组和构件名称。
4. 指定 Java 版本 17。
5. 选择 **ADD DEPENDENCIES**(添加依赖项),然后搜索并选择 **Spring Data MongoDB**。您可以使用 Spring Data MongoDB 依赖项,从此应用程序与 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 集群进行交互。
3\. 选择 **GENERATE**(生成)以生成一个 Spring Boot 项目,其中包含引导所需的全部文件。
4\. 将 ZIP 文件下载到本地计算机上的路径并解压缩文件。
![image.png](https://dev-media.amazoncloud.cn/7f2eda52d71043049a07ea77963fe6b4_image.png "image.png")
如果您使用的是 Amazon Cloud9 IDE,请将 ZIP 文件上传到 Amazon Cloud9 环境并解压缩文件。
### **验证 Maven 依赖项**
在应用程序的目录中找到 `pom.xml` 文件,然后验证是否已按如下方式添加 Spring Data MongoDB 依赖项:
```XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
```
### **定义数据模型**
要在 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 数据库中存储和检索数据,我们先创建一个 POJO 模型或实体类。该实体代表 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 中的集合,并使用注释来定义集合名称、属性、键和其他方面。
在此示例中,您创建一个产品集合和对应的模型对象,该对象将产品的详细信息存储在目录数据库中。您创建具有六个属性的产品模型: `id` 、 `name` 、 `sku` 、 `description` 、 `inventory` 和 `category` 。
[Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 在集合中存储数据。默认情况下,Spring Data 将产品的类或模型映射到名为 `product` 的集合。如果要更改集合的名称,您可以在类上使用 Spring Data MongoDB 的 @Document 注释。在以下示例中,我们使用 `@Document(collection = "products")` 来将集合名称指定为 `products` 。
您可以使用 `@Id` 注释指定文档的主键 `\\_id` 。如果您未指定任何内容,[Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 将在创建文档时生成 `\\_id` 字段。其他属性不添加注释。这会假设它们映射到与属性本身具有相同名称的字段。在项目的目录中,创建一个 `Product.java` 文件,其中具有以下内容:
```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;
}
}
```
为每个属性添加 getter 和 setter 方法。您可以使用特定于 IDE 的快捷方式生成 getter 和 setter 方法。例如,右键单击代码编辑器窗格,选择 Refactoring(重构),然后选择 Generate Getter and Setter in Cloud9(在 Cloud9 中生成 Getter 和 Setter)。
此外,建议覆盖 toString 方法来输出对象,例如,右键单击代码编辑器窗格,选择 Refactoring(重构),然后选择 Generate toString() in Cloud9(在 Cloud9 中生成 toString())
![image.png](https://dev-media.amazoncloud.cn/e8b2b545fc4b4109bc3261ba4a7ebd33_image.png "image.png")
### **在启用 TLS 的情况下进行连接**
要从基于 Java 的 Spring Boot 应用程序连接到启用了 TLS 的 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 集群,您的程序必须使用亚马逊云科技提供的证书颁发机构(CA,Certificate Authority)文件来验证连接。要使用 [Amazon RDS](https://aws.amazon.com/cn/rds/?trk=cndc-detail) CA 证书,请执行以下操作:
1\. 在 tmp 文件夹下创建一个临时 certs 文件夹。您可以根据组织的安全策略来创建用于存储证书的文件夹。本文中,在 tmp 下创建 certs 文件夹:
```Bash
mkdir /tmp/certs/
```
2. 运行以下命令,使用包含在文件中的 CA 证书创建信任存储。请确保更新 <truststorePassword> 。以下 shell 脚本示例将证书捆绑包导入 Linux 操作系统上的信任存储。有关其他选项,请参阅启用了 [TLS](https://docs.aws.amazon.com/documentdb/latest/developerguide/connect_programmatically.html#connect_programmatically-tls_enabled?trk=cndc-detail) 的情况下的连接。
```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
```
### **数据库和连接配置**
设置连接详细信息和 SSL 信任存储需要两个配置文件。首先,在 application.properties 中定义您的 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 连接参数,例如数据库、URI 或主机、端口、用户名和密码。然后在配置类中设置密钥库。
#### **配置 Spring Boot 应用程序属性文件**
要将 Spring Boot 应用程序连接到 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail),我们需要在 `application.properties` 文件中定义数据库配置。您需要配置数据库 URI、数据库名称或主机名、用户名、密码等属性,以及其他与连接相关的属性。要连接到 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 集群,您需要在位于 `src/main/resources` 文件夹的 `application.properties` 文件中指定连接 URI 字符串。
要检索您的 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 集群端点并配置 `application.properties` ,请完成以下步骤:
1\. 在 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 控制台的导航窗格中,选择 **Clusters**(集群)。
2\. 找到您的集群并选择区域集群标识符。
3\. 在 **Connectivity & security**(连接和安全性)选项卡上,复制用于通过 application.
![image.png](https://dev-media.amazoncloud.cn/9605bcc717b642d2b4cb3548d79b648b_image.png "image.png")
连接到集群的命令。
4\. 从复制的连接字符串中删除 `\\&ssl_ca_certs=rds-combined-ca-bundle.pem` ,因为您已经将亚马逊云科技提供的 CA 文件导入了信任存储。\
5\. 将连接 URI 添加到位于您的项目 `src/main/resource`s 文件夹的 `application.properties` 文件中。连接 URI 的键为 `spring.data.mongodb.uri` 。确保复制的连接字符串格式如下:
```js
spring.data.mongodb.uri=mongodb://<用户名>:<密码>@<集群端点>: 27017/?ssl=true&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false
```
或者,您可以单独提供连接详细信息,包括主机名、端口、用户名和密码以及对应的属性键,例如 `spring.data.mongodb.host` 或 `spring.data.mongodb.port` 。有关可用的 Spring Boot 参数配置选项的完整列表,请参阅 Common Application Properties(常用应用程序属性)下的 [Data Properties(数据属性](https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#appendix.application-properties.data?trk=cndc-detail))。
6\. 您也可以选择在 `application.properties` 文件中指定数据库名称:
#### **创建配置类并设置密钥库**
现在属性配置已经完成,您需要定义配置类来设置密钥库属性,以便建立安全连接。
要在应用程序中使用密钥库,请在配置类中设置以下系统属性:
```js
javax.net.ssl.trustStore: <truststore>
javax.net.ssl.trustStorePassword: <truststorePassword>
```
请参阅以下示例配置类。使用 `@Configuration` 注释将该类标记为配置类。具有 `@Configuration` 注释的类由 Spring 容器用作 bean 定义的来源。
```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);
}
}
```
以上是 Spring Boot 中 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 配置的全部内容现在,您可以通过扩展 MongoRepository 开始定义基于接口的存储库类。
### **配置存储库接口**
现在,您可以使用 MongoRepository 访问数据库中的数据。 MongoRepository 提供常用功能,例如创建、读取、更新和删除(CRUD,Create, Read, Update, and Delete)操作。它充当模型与数据库之间的链接。它获取域类(Product)进行管理,并获取域类的 ID 类型作为类型参数。您可以编写几种方法,由存储库为您生成查询。
创建查询 Product 文档的存储库接口,如下所示:
```Java
public interface ProductRepository extends MongoRepository<Product, String> {
}
```
`ProductRepository` 扩展 `MongoRepository` 接口。此接口包含许多操作,包括标准的 CRUD 操作。您将在下一节中定义其他自定义操作。
### 定义服务类
服务类利用了 Spring Data 存储库接口。我们通过引用您在上一步中创建的存储库来定义它:
```Java
@Servicepublic class ProductService { @Autowired private ProductRepository productRepo;}
```
在下一节中,您将在此类上通过添加其他方法进行构建,该节还介绍了 CRUD 示例。
### **使用 CrudRepository**
使用扩展了 `CrudRepository` 的 `MongoRepository` 时,您的存储库可以从 `CrudRepository` 接口的实施类访问基本功能,包括 `save` 、 `count` 、 `findAll` 和 `delete` 方法。您的 `ProductRepository` 接口扩展了 `MongoRepository` ,并可以访问所有基本 CRUD 操作。
我们来逐个探索和测试这些操作。
#### **保存或创建**
首先,您使用 save 方法向集合中添加一些文档。 save 方法获取 Product 对象作为输入,并将产品文档保存到 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 集合中。将以下代码片段添加到您的服务类中:
```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 ");
}
```
#### 计数
在下一个示例中,如果存储库中没有任何方法,则调用服务类中的 count() 方法,对集合中的文档进行计数。
```Java
public long getCount() {
long count = productRepo.count();
System.out.println(" Total number of products : "+count);
return count;
}
```
#### 读取
在此示例中,您执行三种不同的读取操作。您可以按名称或 SKU 提取产品,然后根据类别查找产品列表。
您在存储库( `ProductRepository` )中添加了三种简单方法。第一种方法 `findProductByName` 根据 `name` 属性查询集合。查询筛选条件使用注释 `@Query` 定义,在本例中,注释为 `@Query("{name:'?0'}")` 。第二种方法 `findProductBySKU` 根据 `sku` 属性查询集合,并在查询响应中仅输出 `name` 和 `inventory` 属性。第三种方法 `findAll` 检索特定类别的所有文档。请参阅以下代码:
```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);
}
```
您可以从存储库在服务类中调用这三种方法,按名称、SKU 和类别查找文档。
```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;
}
```
#### 更新
您可以通过传递更新后的实体对象,使用 `save` 方法来更新现有文档。在此示例中,您按 SKU 查询现有产品并将库存增加 10。将以下方法添加到您的服务中:
```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);
}
```
#### 删除
在本示例中,您将创建两个删除操作。首先,您按照 ID 删除一个产品;在第二种方法中,您将删除集合中的所有文档(products)。将以下方法添加到您的服务类中:
```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.");
}
```
### **构建 Spring Boot 应用程序**
默认的 Spring Boot 应用程序已经由 Spring Initializr 在根程序包(例如 `com.example.documentdb` )中创建。在 IDE 中打开默认应用程序:
```Java
@SpringBootApplication
public class DocumentdbApplication {
public static void main(String[] args) {
SpringApplication.run(DocumentdbApplication.class, args);
}
}
```
`CommandLineRunner` 接口表明,当 bean 包含在 `SpringApplication` 中时应该运行,以便在控制台上查看输出。实施 `CommandLineRunner` 接口并为 run 方法提供植入方法。我们使用 `@Autowired` 注释定义对您服务的引用。Spring 使用 `@SpringBootApplication` 注释来初始化应用程序上下文:
```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();
}
}
```
### 运行并测试您的应用程序
使用以下 Maven 命令运行 Spring Boot 应用程序:
```Bash
mvn spring-boot:run
```
以下屏幕截图是 Spring Boot 应用程序的示例输出。
![image.png](https://dev-media.amazoncloud.cn/5608d4cd31a4426bad886032baaf7eb9_image.png "image.png")
您做到了! 您已成功从 Spring Boot 应用程序连接到 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail)。
### 总结
在这篇文章中,您了解了如何通过简单的应用程序将 [Amazon DocumentDB](https://aws.amazon.com/cn/documentdb/?trk=cndc-detail) 与 Spring Boot 应用程序集成,该应用程序使用 Spring Data MongoDB 将对象保存到数据库以及从数据库中提取对象,所有这些过程都无需编写具体的存储库实施,而且配置简单。
这篇文章中使用的示例在 [GitHub](https://github.com/aws-samples/amazon-documentdb-samples/tree/master/blogs/docdb-springboot?trk=cndc-detail) 上作为示例项目提供。
Original URL:
https://aws.amazon.com/cn/blogs/database/integrate-your-spring-boot-application-with-amazon-documentdb/?trk=cndc-detail
![开发者尾巴.gif](https://dev-media.amazoncloud.cn/b951cfe1becf49bbb2ee1ea0a9fbbfb9_%E5%BC%80%E5%8F%91%E8%80%85%E5%B0%BE%E5%B7%B4.gif "开发者尾巴.gif")