赞
踩
目录
Spring数据框架在应用程序中被广泛使用,因为它使访问不同类型的持久性存储变得更容易。这篇文章将展示如何使用SpringDataMongoDB以实现批量插入。
BulkOperations是一个包含要应用于数据库的写入操作列表的接口。它们可以是InsertOne、updateOne updateMany、replaceOne deleteOne deleteMany的任意组合
bulkOperation可以是有序的,也可以是无序的。有序操作将按顺序应用,如果检测到错误,将返回错误代码。无序操作将并行应用,因此可能更快,但应用程序有责任检查操作过程中是否存在错误。有关更多信息,请参阅MongoDB文档的批量写入操作部分。
下面的兼容性表总结了Spring Data版本与MongoDB驱动/数据库版本的关系。

POM 文件将指定应用程序将使用的 Spring 数据版本。必须注意使用使用兼容版本的MongoDB Java驱动程序的Spring Data版本。
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-mongodb</artifactId>
- <version>2.7.2</version>
- </dependency>
顶级类是一个SpringBootApplication,它实现了CommandLineRunner,如下所示:
- @SpringBootApplication
- public class SpringDataBulkInsertApplication implements CommandLineRunner {
-
- @Value("${documentCount}")
- private int count;
- private static final Logger LOG = LoggerFactory
- .getLogger(SpringDataBulkInsertApplication.class);
-
- @Autowired
- private CustomProductsRepository repository;
-
- public static void main(String[] args) {
- SpringApplication.run(SpringDataBulkInsertApplication.class, args);
- }
-
-
- @Override
- public void run(String... args) {
-
- repository.bulkInsertProducts(count);
- LOG.info("End run");
- }
- }

现在我们需要编写一些类来实现我们的批量插入应用程序。
- @Configuration
- public class MongoConfig {
- @Value("${mongodb.uri}")
- private String uri;
-
- @Value("${mongodb.database}")
- private String databaseName;
-
- @Value("${truststore.path}")
- private String trustStorePath;
- @Value("${truststore.pwd}")
- private String trustStorePwd;
-
- @Value("${mongodb.atlas}")
- private boolean atlas;
-
- @Bean
- public MongoClient mongo() {
- ConnectionString connectionString = new ConnectionString(uri);
- MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
- .applyConnectionString(connectionString)
- .applyToSslSettings(builder -> {
- if (!atlas) {
- // Use SSLContext if a trustStore has been provided
- if (!trustStorePath.isEmpty()) {
- SSLFactory sslFactory = SSLFactory.builder()
- .withTrustMaterial(Paths.get(trustStorePath), trustStorePwd.toCharArray())
- .build();
- SSLContext sslContext = sslFactory.getSslContext();
- builder.context(sslContext);
- builder.invalidHostNameAllowed(true);
- }
- }
- builder.enabled(true);
- })
- .build();
- return MongoClients.create(mongoClientSettings);
- }
-
- @Bean
- public MongoTemplate mongoTemplate() throws Exception {
- return new MongoTemplate(mongo(), databaseName);
- }
- }

在这个实现中,我们使用一个标志mongodb.atlas来指示这个应用程序将连接到atlas。如果标志为false,则可以使用trustStore创建SSL上下文。这以trustStore.path指向的信任库文件的形式为根证书颁发机构提供证书,在创建时受密码(trustStore.pwd)保护。如果需要,客户端还可以提供密钥库文件,但这并没有实现。
参数mongodb.uri应该包含一个有效的mongodb uri。URI包含客户端连接的主机、用户凭据等。
MongoDB集合与其包含的文档之间的关系是通过由@Document注释修饰的类实现的。此类定义文档的字段,批注定义集合的名称。
- @Document("products")
- public class Products {
-
- private static final Logger LOG = LoggerFactory
- .getLogger(Products.class);
- @Id
- private String id;
- private String name;
- private int qty;
- private double price;
- private Date available;
- private Date unavailable;
- private String skuId;
需要为每个字段定义设置器和获取器。@Id注释表示我们的默认索引。如果未指定此字段,MongoDB将分配一个唯一的ObjectId值。
MongoDB驱动支持在一个操作中插入一个文档集合。MongoOperations 接口中的下列方法支持这一功能。
insert 方法: 以一个 Collection 作为第一个参数。它们在一次批量写入数据库中插入一个对象的列表。
存储库由两个类实现,一个是接口,另一个是实现接口。存储库类充实了应用程序与数据库的交互。存储库中的一个方法负责批量插入:
- @Component
- public class CustomProductsRepositoryImpl implements CustomProductsRepository {
-
- private static final Logger LOG = LoggerFactory
- .getLogger(CustomProductsRepository.class);
-
- @Autowired
- MongoTemplate mongoTemplate;
-
- public int bulkInsertProducts(int count) {
-
- LOG.info("Dropping collection...");
- mongoTemplate.dropCollection(Products.class);
- LOG.info("Dropped!");
-
- Instant start = Instant.now();
- mongoTemplate.setWriteConcern(WriteConcern.W1.withJournal(true));
-
- Products [] productList = Products.RandomProducts(count);
- BulkOperations bulkInsertion = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, Products.class);
-
- for (int i=0; i<productList.length; ++i)
- bulkInsertion.insert(productList[i]);
-
- BulkWriteResult bulkWriteResult = bulkInsertion.execute();
-
- LOG.info("Bulk insert of "+bulkWriteResult.getInsertedCount()+" documents completed in "+ Duration.between(start, Instant.now()).toMillis() + " milliseconds");
- return bulkWriteResult.getInsertedCount();
- }
- }

在这个例子中,我们创建了一个随机的产品列表,然后这些产品被无序地批量插入。我们指定了写问题1,这意味着一旦Primary将操作写入日志,服务器就会确认该操作。
这种写入问题会导致更快的插入,但如果Primary崩溃或发生选举,并且数据尚未复制,则有可能丢失数据。为了避免这种危险,请使用“关注多数”。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/55993
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。