diff --git a/snooty.toml b/snooty.toml index 779c5740d..d841f5e34 100644 --- a/snooty.toml +++ b/snooty.toml @@ -19,6 +19,7 @@ toc_landing_pages = [ "/api-documentation", "/security", "/security/auth", + "/integrations" ] sharedinclude_root = "https://raw.githubusercontent.com/10gen/docs-shared/main/" diff --git a/source/includes/integrations/spring-data-tutorial-code/main/java/MongoConfig.java b/source/includes/integrations/spring-data-tutorial-code/main/java/MongoConfig.java new file mode 100644 index 000000000..9075685a7 --- /dev/null +++ b/source/includes/integrations/spring-data-tutorial-code/main/java/MongoConfig.java @@ -0,0 +1,38 @@ +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; + +// start-mongoconfig +@Configuration +public class MongoConfig { + @Value("${mongodb.uri}") + private String uri; + @Value("${mongodb.database}") + private String databaseName; + + @Bean + public MongoClient mongo() { + + 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(mongo(), databaseName); + } +} +// end-mongoconfig diff --git a/source/includes/integrations/spring-data-tutorial-code/main/java/MyProjectName.java b/source/includes/integrations/spring-data-tutorial-code/main/java/MyProjectName.java new file mode 100644 index 000000000..77c26620f --- /dev/null +++ b/source/includes/integrations/spring-data-tutorial-code/main/java/MyProjectName.java @@ -0,0 +1,35 @@ +package com.mongodb.examples.springdatabulkinsert; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +// start-application +@SpringBootApplication +public class MyProjectName implements CommandLineRunner { + + @Value("${documentCount}") + private int count; + private static final Logger LOG = LoggerFactory + .getLogger(MyProjectName.class); + + @Autowired + private ProductRepository repository; + + public static void main(String[] args) { + SpringApplication.run(MyProjectName.class, args); + } + + @Override + public void run(String... args) throws Exception { + + repository.bulkInsertProducts(count); + LOG.info("End run"); + System.exit(1); + } +} +// end-application diff --git a/source/includes/integrations/spring-data-tutorial-code/main/java/Product.java b/source/includes/integrations/spring-data-tutorial-code/main/java/Product.java new file mode 100644 index 000000000..2460bce93 --- /dev/null +++ b/source/includes/integrations/spring-data-tutorial-code/main/java/Product.java @@ -0,0 +1,107 @@ +package com.mongodb.examples.springdatabulkinsert; + +import net.datafaker.Faker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.util.Date; +import java.util.Random; + +// start-products-class +@Document("products") +public class Product { + + 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; + + 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 Product [] RandomProducts( int count) { + + Faker faker = new Faker(); + Random rand = new Random(); + + Product [] retProds = new Product[count]; + for (int i=0; i +documentCount=25000 +# end-mongoconfig-properties diff --git a/source/includes/integrations/spring-data-tutorial-code/pom.xml b/source/includes/integrations/spring-data-tutorial-code/pom.xml new file mode 100644 index 000000000..4b345e2ad --- /dev/null +++ b/source/includes/integrations/spring-data-tutorial-code/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.2.5 + + + com.mongodb.examples + SpringDataBulkInsert + SpringDataBulkInsert + SpringDataBulkInsert + + 17 + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + + + org.projectlombok + lombok + true + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + + net.datafaker + datafaker + 2.4.3 + + + + + io.github.hakky54 + sslcontext-kickstart + 8.3.7 + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/source/integrations.txt b/source/integrations.txt index af3ad44f1..a012fdcdc 100644 --- a/source/integrations.txt +++ b/source/integrations.txt @@ -18,6 +18,10 @@ Third-Party Integrations :depth: 2 :class: singlecol +.. toctree:: + + Tutorial: Spring Data Framework + Overview -------- diff --git a/source/integrations/spring-data-integration.txt b/source/integrations/spring-data-integration.txt new file mode 100644 index 000000000..6f0ad0692 --- /dev/null +++ b/source/integrations/spring-data-integration.txt @@ -0,0 +1,271 @@ +.. _java-spring-data: +.. original URL: https://www.mongodb.com/developer/languages/java/java-spring-bulk-writes/ + +=========================================== +Tutorial: Spring Data Framework Integration +=========================================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 3 + :class: singlecol + +.. facet:: + :name: genre + :values: tutorial + +.. meta:: + :description: Build an application using the Spring Data Framework and the MongoDB Java driver. + :keywords: spring, tutorial, bulk insert, code example + +Overview +-------- + +In this tutorial, you can learn how to use `Spring Data +MongoDB `__ with the +{+driver-short+} to perform high-performance bulk inserts in a Spring Boot application. + +Spring Data MongoDB +~~~~~~~~~~~~~~~~~~~ + +Spring Data MongoDB is the official Spring Data ODM for MongoDB. It allows you to +interact with MongoDB by using plain old Java objects (POJOs) and repository +abstraction. It supports MongoDB-specific features like dynamic queries, +indexing, and nested document mapping while reducing boilerplate code such as +manual ``find()`` and ``update()`` calls. + +Dependency Injection +~~~~~~~~~~~~~~~~~~~~ + +Dependency injection (DI) is a core principle of the Spring Framework. It +allows objects, called beans, to be created and managed by the Spring container, +then injected into other beans that use them. This is distinct from typical +object-oriented development where classes are responsible for initializing and +constructing the objects they use. + +For more information about dependency injection, see the `Dependency +Injection `__ +page of the Spring Framework documentation. + +The Spring Data BulkOperations Interface +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +BulkOperations is a Spring Data MongoDB interface that contains a list of write +operations that can be applied to your database. It can handle any combination of +the following operations which map to similar {+driver-long+} operations: + +- ``insert`` +- ``updateOne`` +- ``updateMany`` +- ``replaceOne`` +- ``deleteOne`` +- ``deleteMany`` +- ``upsert`` + +A BulkOperation can be ordered or unordered. Ordered bulk operations run operations +sequentially, and if an error is detected, return with an error code. +Unordered operations are run in parallel, which means they are typically faster. +However, you must manually check if there were errors during the operations. + +For more information about bulk operations, see the following resources: + +- `BulkOperations + `__ + in the Spring Framework API documentation +- :ref:`Bulk Write Operations ` in this guide +- :manual:`Bulk Write Operations ` in the MongoDB server manual + +Tutorial +-------- + +You can find the completed sample app for this tutorial in the +:github:`SpringDataBulkInsert sample project +` GitHub repository. + +.. note:: Imports Not Specified + + The import statements required for the files in the tutorial have not been included on the page. See the :github:`GitHub repository` for complete files. + +Prerequisites +~~~~~~~~~~~~~ + +Ensure you have the following components installed and set up before you start +this tutorial: + +- `Java 8 or later `__ +- `Maven `__ +- A :atlas:`MongoDB Atlas cluster ` +- A new `Spring Boot application `__ + +Add Dependencies +~~~~~~~~~~~~~~~~ + +Ensure that you use a Spring Data MongoDB version that is compatible with the +{+driver-long+} and Java versions you are using. For compatibility specifications, see +the `Requirements +`__ page +of the Spring Data MongoDB documentation, and the :ref:`Compatibility +` page of this guide. + +.. note:: + + If you used the `Spring Initializr `__ or a clone of the :github:`Spring Boot sample project ` to create your project, versioning compatibility has already been accounted for, and the ``spring-boot-starter-data-mongodb`` component will already be included in your ``pom.xml`` file. + +Add the following dependencies to your ``pom.xml``: + +.. code-block:: xml + + + org.springframework.boot + spring-boot-starter-data-mongodb + 3.2.5 + + + net.datafaker + datafaker + 2.4.3 + + +The ``datafaker`` dependency is used to generate a large quantity of ``Product`` +objects to use in the bulk write operation. + +Configure your MongoClient +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``MongoConfig`` class contains the configuration for the ``MongoClient`` +that will allow the Spring Data framework to interact with the MongoDB server, +and sets other configuration options. For more information about configuration +options, see the :ref:`Specify Connection Options ` +page of this guide. + +This application uses ``@Configuration`` annotations for classes, ``@Bean`` +annotations for methods, and ``@Value`` annotations for parameter conversion. +These annotations allow the Spring IoC container to manage objects. For a +detailed explanation of these annotations, see the following sections of the +Spring Data framework guide: + +- ``@Configuration`` and ``@Bean`` annotations: `Java-based Container + Configuration + `__ +- ``@Value`` annotations: `Using @Value + `__ + +Create a ``MongoConfig.java`` file and add the following configuration and +template classes to set up your MongoDB connection: + +.. literalinclude:: /includes/integrations/spring-data-tutorial-code/main/java/MongoConfig.java + :start-after: // start-mongoconfig + :end-before: // end-mongoconfig + :language: java + :dedent: + +.. note:: API vs Interface + + This implementation uses the ``MongoTemplate`` API, rather than extending a + Spring Data repository interface such as ``MongoRepository``, to allow for + fine-grained control over bulk operations. + +Set the values of your connection string (``mongodb.uri``), +database name (``mongodb.database``), and bulk operation count (``documentCount``) in your ``application.properties`` file: + +.. literalinclude:: /includes/integrations/spring-data-tutorial-code/main/resources/application.properties + :start-after: # start-mongoconfig-properties + :end-before: # end-mongoconfig-properties + :language: console + :dedent: + +This tutorial uses a database named ``bulk``, and creates 25000 documents to save. Replace the ```` placeholder with a connection string for your Atlas deployment. For +more information, see the :ref:`` section of +this guide. + +Map Your Object to a Document +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Mapping a class to a collection allows the Spring IoC container to store objects +as MongoDB documents. You can use the ``@Document`` annotation to specify which +collection a class maps to. For more information about mapping objects to MongoDB +documents, see the `Mapping Annotation Overview +`__ +section of the Spring Data MongoDB documentation. + +The ``@Id`` annotation in the following code indicates that the ``id`` field +maps to the ``_id`` field which is used as a unique identifier in MongoDB documents. You can choose any field of +any type, except arrays, to be the unique identifier. For more information, see +the `How the _id field is handled in the mapping layer +`__ +section of the Spring Data MongoDB documentation. + +Create a ``Product.java`` file to define your ``Product`` class and map it to +your ``products`` collection with the following code: + +.. literalinclude:: /includes/integrations/spring-data-tutorial-code/main/java/Product.java + :start-after: // start-products-class + :end-before: // end-products-class + :language: java + :dedent: + +The ``Product`` class includes a static method that generates an array of +``Product`` objects. You may also define getters and setters for each field. + +Define a Repository to Store Your Products +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``ProductRepository`` will manage a collection of ``Product`` objects. +Your ``ProductRepository`` references the client creation methods defined in the ``MongoConfig`` class, which you +annotated with ``@Bean``. By using the ``@Autowired`` annotation with the +``mongoTemplate`` variable together with a constructor that includes +``mongoTemplate`` as an argument, the Spring container uses constructor +injection to inject a ``mongoTemplate`` dependency. For more information about +constructor injection, see the `Constructor-based Dependency Injection +`__ +section of the Spring Framework documentation. + +Create a ``ProductRepository.java`` file and define your ``ProductRepository`` +class to manage a collection of ``Product`` objects with the following code: + +.. literalinclude:: /includes/integrations/spring-data-tutorial-code/main/java/ProductRepository.java + :start-after: // start-productrepo + :end-before: // end-productrepo + :language: java + :dedent: + +The ``bulkInsertProducts()`` method uses unordered bulk inserts, which can +improve performance by not guaranteeing the order of operations. + +Perform a Bulk Operation +~~~~~~~~~~~~~~~~~~~~~~~~ + +The main application class triggers the ``ProductRepository`` to generate the +specified number of ``Product`` objects and save them to your MongoDB database. It uses +the ``@Autowired`` annotation to inject a ``ProductRepository``, and implements logging. + +Add the following code to your main class to run your application: + +.. literalinclude:: /includes/integrations/spring-data-tutorial-code/main/java/MyProjectName.java + :start-after: // start-application + :end-before: // end-application + :language: java + :dedent: + +Conclusion +---------- + +Spring Data MongoDB provides a high-level abstraction for working with MongoDB. +It can simplify application architecture by supporting automatic dependency +injection, which eliminates the need for manual client configuration and complex +query handling. By reducing boilerplate code and supporting object-oriented data access, it can +streamline data access and promote a clear separation of concerns. + +More Resources +-------------- + +For more information about the Spring Data Framework, see the +following resources: + +- `Spring Framework Documentation `__ +- `Spring Data for MongoDB reference `__ +- `Spring Data for MongoDB API documentation `__ + +For support or to contribute to the MongoDB Community, see the `MongoDB Developer Community `__. \ No newline at end of file