Docs 菜单
Docs 主页
/ /

教程:Spring Data Framework 集成

在本教程中,您可以学习;了解如何将 Spring Data MongoDB 与Java驾驶员结合使用,以便在 Spring Boot应用程序中执行高性能批量插入。

Spring Data MongoDB是适用于MongoDB的官方 Spring Data对象文档映射器 (ODM)。它允许您使用普通的旧Java对象 (POJO) 和存储库抽象与MongoDB进行交互。它支持MongoDB特有的功能,如动态查询、索引和嵌套文档映射,同时减少样板代码,如手动 find()update() 调用。

Spring Boot 是一个构建在 Spring 框架之上的框架。它添加了自动配置、默认值和生产就绪功能,以简化构建基于 Spring 的Java应用程序,包括与 Spring Data MongoDB 的集成。有关更多信息,请参阅 Spring Boot 文档。

依赖注入 (DI) 是 Spring 框架的核心原则。它允许 Spring容器创建和管理称为 Bean 的对象,然后将它们注入到使用它们的其他 Bean 中。这与典型的面向对象开发不同,在典型的面向对象开发中,类负责初始化和构造它们使用的对象。

有关依赖项注入的更多信息,请参阅 Spring 框架文档的依赖项注入页面。

BulkOperations 是一个 Spring Data MongoDB接口,其中包含可应用于数据库的写入操作列表。它可以处理以下操作的任意组合,这些操作映射到类似的MongoDB Java驱动程序操作:

  • insert

  • updateOne

  • updateMany

  • replaceOne

  • deleteOne

  • deleteMany

  • upsert

BulkOperation 可以是有序的,也可以是无序的。有序批量操作按顺序运行操作,如果检测到错误,则返回并附带错误代码。无序操作并行运行,这意味着它们通常速度更快。但是,您必须手动检查操作过程中是否出现错误。

有关批量操作的更多信息,请参阅以下资源:

  • Spring 框架API文档中的 BulkOperations

  • 本指南中的批量写入操作

  • MongoDB Server手册中的批量写入操作

您可以在 SpringDataBulkInsert示例项目GitHub存储库中找到本教程的完整示例应用。

注意

未指定导入

此页面不包含本教程中的文件所需的 import 语句。请参阅 GitHub存储库以获取完整文件。

在开始本教程之前,请确保已安装并设立以下组件:

确保您使用的 Spring Data MongoDB版本与您正在使用的MongoDB Java驱动程序和Java版本兼容。有关兼容性规范,请参阅 Spring Data MongoDB文档的“要求”页面和本指南的“兼容性”页面。

注意

如果您使用 Spring Initializr Spring Boot示例项目的克隆来创建项目,则已考虑版本控制兼容性,并且 spring-boot-starter-data-mongodb组件已包含在pom.xml 文件中。

将以下依赖项添加到您的 pom.xml文件中:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>3.2.5 </version>
</dependency>
<dependency>
<groupId>net.datafaker</groupId>
<artifactId>datafaker</artifactId>
<version>2.4.3</version>
</dependency>

datafaker 依赖项用于生成大量 Product 对象以在批量写入操作中使用。

MongoConfig类包含MongoClient 对象的配置,该对象将允许 Spring Data框架与MongoDB Server交互,并设置其他配置选项。有关配置选项的更多信息,请参阅本指南的“指定连接选项”页面。

此应用程序对类使用 @Configuration 注解,对方法使用 @Bean 注解,对参数转换使用 @Value 注解。这些注解允许 Spring 控制反转 (IoC)容器管理对象。有关这些注解的详细说明,请参阅 Spring Data框架指南的以下部分:

创建 MongoConfig.java文件并添加以下配置和模板类以设立MongoDB连接:

package com.mongodb.examples.springdatabulkinsert;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
@Configuration
public class MongoConfig {
@Value("${mongodb.uri}")
private String uri;
@Value("${mongodb.database}")
private String databaseName;
@Bean
public MongoClient mongoClient() {
ConnectionString connectionString = new ConnectionString(uri);
MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.build();
return MongoClients.create(mongoClientSettings);
}
@Bean
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongoClient(), databaseName);
}
}

注意

API与接口

此实施使用 MongoTemplate API,而不是扩展 MongoRepository 等 Spring 数据存储库接口,以允许对批量操作进行细粒度控制。

application.properties文件中设置连接字符串(mongodb.uri)、数据库名称 (mongodb.database) 和批量操作计数 (documentCount) 的值:

mongodb.database=bulk
mongodb.uri=<connection string>
documentCount=25000

本教程使用名为bulk 25的数据库,并创建要保存的,000 文档。将<connection string> 占位符替换为Atlas部署的连接字符串。有关更多信息,请参阅本指南的“创建连接字符串”部分。

将类映射到集合允许 Spring IoC容器将对象存储为MongoDB文档。您可以使用@Document 注解来指定类映射到哪个集合。有关将对象映射到MongoDB文档的更多信息,请参阅 Spring Data MongoDB文档的映射注解概述部分。

@Id以下代码中的 注解表示对象id 字段映射到文档_id 字段,该字段用作MongoDB文档中的唯一标识符。您可以选择任何类型(数组除外)的任何字段作为唯一标识符。有关更多信息,请参阅 Spring Data MongoDB文档的映射层中如何处理_id字段部分。

使用以下代码创建 Product.java文件,以定义 Product 类并将其映射到 products集合:

@Document("products")
public class Product {
private static final Logger LOG = LoggerFactory.getLogger(Product.class);
@Id
private String id;
private String name;
private int qty;
private double price;
private Date available;
private Date unavailable;
private String skuId;
public Product(String name, int qty, double price, Date available, Date unavailable, String skuId) {
this.name = name;
this.qty = qty;
this.price = price;
this.available = available;
this.unavailable = unavailable;
this.skuId = skuId;
}
public static List<Product> randomProducts(int count) {
Faker faker = new Faker();
Random rand = new Random();
List<Product> retProds = new ArrayList<>(count);
for (int i = 0; i < count; ++i) {
Product product = new Product(faker.animal().name(),
1 + rand.nextInt(998),
10.0 + rand.nextInt(9999),
new Date(), new Date(),
faker.idNumber().valid());
retProds.add(product);
}
return retProds;
}
// Getters and setters
}

Product 类包含一个生成 Product 对象大量的静态方法。您还可以为字段定义 getter 和 setter。

ProductRepository对象将管理Product 对象的集合。您的ProductRepository 对象必须注入MongoTemplate MongoConfig类中生成的 bean。通过将@Autowired 注解与包含mongoTemplate 作为参数的构造函数一起使用,Spring容器会使用构造函数注入来注入mongoTemplate 依赖项。有关构造函数注入的更多信息,请参阅 Spring 框架文档中基于构造函数的依赖注入部分。

使用以下代码创建 ProductRepository.java文件并定义 ProductRepository 类来管理Product 对象的集合:

@Repository
public class ProductRepository {
private static final Logger LOG = LoggerFactory
.getLogger(ProductRepository.class);
private final MongoTemplate mongoTemplate;
@Autowired
public ProductRepository(MongoTemplate mongoTemplate){
this.mongoTemplate = mongoTemplate;
}
public void updateProductQuantity(String name, int newQuantity) {
Query query = new Query(Criteria.where("name").is(name));
Update update = new Update();
update.set("quantity", newQuantity);
UpdateResult result = mongoTemplate.updateFirst(query, update, Product.class);
if (result == null)
LOG.error("No documents updated");
else
LOG.info(result.getModifiedCount() + " document(s) updated..");
}
public int bulkInsertProducts(int count) {
LOG.info("Dropping collection...");
mongoTemplate.dropCollection(Product.class);
LOG.info("Dropped!");
Instant start = Instant.now();
mongoTemplate.setWriteConcern(WriteConcern.W1.withJournal(true));
List<Product> productList = Product.randomProducts(count);
BulkOperations bulkInsertion = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, Product.class);
bulkInsertion.insert(productList);
BulkWriteResult bulkWriteResult = bulkInsertion.execute();
LOG.info("Bulk insert of " + bulkWriteResult.getInsertedCount() + " documents completed in " + Duration.between(start, Instant.now()).toMillis() + " milliseconds");
return bulkWriteResult.getInsertedCount();
}
}

bulkInsertProducts() 方法使用无序批量插入,可通过不保证操作顺序来提高性能。

主应用程序程序类会触发 ProductRepository 生成指定数量的 Product 对象并将它们保存到MongoDB 数据库中。它使用 @Autowired 注解注入 ProductRepository,并实施日志记录。

将以下代码添加到主类以运行应用程序:

@SpringBootApplication
public class SpringDataBulkInsertApplication implements CommandLineRunner {
@Value("${documentCount}")
private int count;
private static final Logger LOG = LoggerFactory
.getLogger(SpringDataBulkInsertApplication.class);
@Autowired
private ProductRepository repository;
public static void main(String[] args) {
SpringApplication.run(SpringDataBulkInsertApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
repository.bulkInsertProducts(count);
LOG.info("End run");
System.exit(0);
}
}

Spring Data MongoDB为使用MongoDB提供了高级抽象。它可以通过支持自动依赖项注入来简化应用程序架构,从而无需手动进行客户端配置和复杂的查询处理。通过减少样板代码和支持面向对象的数据访问,它可以简化数据访问并促进明确的关注点分离。

有关 Spring 和 Spring Data MongoDB框架的更多信息,请参阅以下资源:

如需支持或为MongoDB Community做出贡献,请参阅MongoDB开发者社区。

后退

第三方集成

在此页面上