Previous Next JavaScript must be enabled to correctly display this content

## Accessing Oracle NoSQL Database Using Spring Data Framework

Learn to access Oracle NoSQL Database from Spring using Oracle NoSQL Database SDK for Spring Data.

Using the Spring Data Framework, you can set up a connection with Oracle NoSQL Database nonsecure store, insert a row in a table, and then retrieve the data from the table.

Example 2-1 Accessing NoSQL Database using Spring Data Framework

The following example shows how to set up a Maven Project and then add the following classes/interfaces:

- `AppConfig` class
- `Student` class
- `StudentRepository` interface
- `App` class

After that, you will run the Spring application to get the required output. The following steps discuss this in detail.

1. Setting up a Maven project:

   Set up a Maven project with the required POM file dependencies. For details, see About the Oracle NoSQL Database SDK for Spring Data.

2. Setting up an Appconfig class:

   Set up the `AppConfig` class that extends the `AbstractNosqlConfiguration` class to provide a `NosqlDbConfig` Spring bean. The `NosqlDbConfig` Spring bean describes how to connect to the Oracle NoSQL Database.

       import oracle.nosql.driver.kv.StoreAccessTokenProvider;

       import com.oracle.nosql.spring.data.config.AbstractNosqlConfiguration;
       import com.oracle.nosql.spring.data.config.NosqlDbConfig;
       import com.oracle.nosql.spring.data.repository.config.EnableNosqlRepositories;

       import org.springframework.context.annotation.Bean;
       import org.springframework.context.annotation.Configuration;

       /* The @Configuration annotation specifies that this class can be
         used by the Spring Data Framework as a source of bean definitions.*/
       @Configuration
       /* annotation to enable NoSQL repositories.*/
       @EnableNosqlRepositories
       public class AppConfig extends AbstractNosqlConfiguration {

           public static NosqlDbConfig nosqlDBConfig =
               new NosqlDbConfig("hostname:port", new StoreAccessTokenProvider());

       /* The @Bean annotation tells the Spring Data Framework that the returned object
         must be registered as a bean in the Spring application.*/
       @Bean
           public NosqlDbConfig nosqlDbConfig() {
               return nosqlDBConfig;
           }
       }

   Note:

   See Setting up the Connection section to know more about connecting to an Oracle NoSQL Database secure store.
3. Defining an entity class:

   Create a new package and add the following `Student` entity class to persist. This entity class represents a table in the Oracle NoSQL Database and an instance of this entity corresponds to a row in that table.

   Supply the `@NosqlId` annotation to indicate that the `id` field will act as the ID and be the primary key of the underlying storage table and `generated=true` attribute to specify that this ID will be autogenerated by a sequence.

   If the ID field type is a String, a UUID will be used. If the ID field type is integer or long, a "GENERATED ALWAYS as IDENTITY (NO CYCLE)" sequence is used.

   For details on all the Spring Data classes, methods, interfaces, and examples see SDK for Spring Data API Reference.

       import com.oracle.nosql.spring.data.core.mapping.NosqlId;
       import com.oracle.nosql.spring.data.core.mapping.NosqlTable;

       /* The @NosqlTable annotation specifies that
         this class will be mapped to an Oracle NoSQL Database table.*/
       @NosqlTable
       public class Student {
           /* The @NosqlId annotation specifies that this field will act
             as the ID field. And the generated=true attribute specifies
             that this ID will be autogenerated by a sequence.*/
           @NosqlId(generated = true)
           long id;
           String firstName;
           String lastName;
           /* public or package protected constructor required when retrieving from database */
           public Student() {
           }
           /* This method overrides the toString() method, and then
             concatenates id, firstname, and lastname, and then returns a String*/
           @Override
           public String toString() {
               return "Student{" +
                   "id=" + id + ", " +
                   "firstName=" + firstName + ", " +
                   "lastName=" + lastName +
                   '}';
           }
       }

   When a table is created through the Spring Data application, a schema is created automatically, which includes two columns - the primary key column (types String, integer, long, or timestamp) and a JSON column called `kv_json_`.

   If a table exists already, it must comply with the generated schema.

   Note:

   - You can set the table level TTL by supplying the `ttl()` and `ttlUnit()` parameters in the `@NosqlTable` annotation of the entity class. For more details, see Setting TTL values.
   - You can set the default `TableLimits` for Oracle NoSQL Database Cloud Service tables in the `@NosqlDbConfig` instance using `NosqlDbConfig.getDefaultCapacityMode()`, `NosqlDbConfig.getDefaultStorageGB()`, `NosqlDbConfig.getDefaultReadUnits()`, and `NosqlDbConfig.getDefaultWriteUnits()` methods. The `TableLimits` can also be specified per table if the `@NosqlTable` annotation is used, through `capacityMode`, `readUnits`, `writeUnits`, and `storageGB` fields as shown in the following code sample.

         /* Set the TableLimits and TTL values. */
         @NosqlTable(readUnits = 50, writeUnits = 50, storageGB = 25)

4. Declaring a repository that extends NosqlRepository:

   Create the following `StudentRepository` interface. This interface must extend the `NosqlRepository` interface and provide the entity class and the data type of the primary key in that class as parameterized types to the `NosqlRepository` interface. This `NosqlRepository` interface provides methods that can be used to retrieve data from the database.

       import com.oracle.nosql.spring.data.repository.NosqlRepository;

       /* The Student is the entity class, and Long is the data type of the
         primary key in the Student class. This interface implements a derived query
         findByLastName and returns an iterable instance of the Student class.*/

       public interface StudentRepository extends NosqlRepository<Student, Long> {
           /* The Student table is searched by lastname and
             returns an iterable instance of the Student class.*/
           Iterable<Student> findByLastName(String lastname);
       }

5. Creating an application class:

   Code the functionality as required by implementing any of the various interfaces provided by the Spring Data Framework. This example uses the `CommandLineRunner` interface to show the application code that implements the run method and has the main method. For more information about setting up a Spring boot application, see Spring Boot.

   In Spring data applications, the tables are automatically created at the beginning of the application when the entities are initialized unless `@NosqlTable.autoCreateTable` is set to `false`.

   You can create the application code to insert data to the table, read the rows from the table, and also run the queries as follows:

   - Adding and deleting data: Use one of these methods to add rows to the table - `NosqlRepository.save(entity_object)`, `saveAll(Iterable<T> iterable)`, or `NosqlTemplate.insert(entity)`. To delete any exisiting rows from the table, you can use one of these methods - `NosqlRepository.deleteById()`, `delete()`, `deleteAll(Iterable<? extends T> entities)`, `deleteAll()` or use`NosqlTemplate.delete()`, `deleteAll()`, `deleteById()`, `deleteInShard()`.

     In the following code sample, you first delete the rows from the `Student` table using the `NosqlRepository.deleteAll()` method. This ensures the deletion of all the rows from the table if the table already preexists in the database. You then use the `NosqlRepository.save(entity_object)` method to add the rows to the table. You create and save two student entities.

         import com.oracle.nosql.spring.data.core.NosqlTemplate;

         import org.springframework.beans.factory.annotation.Autowired;
         import org.springframework.boot.CommandLineRunner;
         import org.springframework.boot.SpringApplication;
         import org.springframework.boot.autoconfigure.SpringBootApplication;
         import org.springframework.context.ConfigurableApplicationContext;

         /* The @SpringBootApplication annotation helps you to build
           an application using Spring Data Framework rapidly.*/
         @SpringBootApplication
         public class App implements CommandLineRunner {

             /* The annotation enables Spring Data Framework to look up the
               configuration file for a matching bean.*/
             @Autowired
             private StudentRepository repo;

             public static void main( String[] args ) {
                 ConfigurableApplicationContext ctx =
                     SpringApplication.run(App.class, args);
                 SpringApplication.exit(ctx, () -> 0);
                 ctx.close();
                 System.exit(0);
             }

             @Override
             public void run(String... args) throws Exception {

                 /* Delete all the existing rows of data, if any, in the Student table.*/
                 repo.deleteAll();

                 /* Create a new Student instance and load values into it.*/
                 Student s1 = new Student();
                 s1.firstName = "John";
                 s1.lastName = "Doe";

                 /* Save the Student instance.*/
                 repo.save(s1);

                 /* Create a new Student instance and load values into it.*/
                 Student s2 = new Student();
                 s2.firstName = "John";
                 s2.lastName = "Smith";

                 /* Save the Student instance.*/
                 repo.save(s2);
            }
         }

     The `@NosqlId` annotation in the `Student` entity class specifies that the `id` field will act as the ID and be the primary key of the underlying storage table. The rest of the entity fields, that is, the `firstName` and `lastName` fields are stored in the JSON column.

   - Reading data: Use one of these methods to read the data from the table - `NosqlRepository.findById()`, `findAllById()`, `findAll()` or using `NosqlTemplate.find()`, `findAll()`, `findAllById()`.

     In the following code sample, you use the `NosqlRepository.findAll()` method to read all the rows from the table. You select all the rows from the `Student` table and supply them to an iterable instance. Print the values to the output from the iterable object.

            System.out.println("\nfindAll:");
              /* Selects all the rows in the Student table
                and load it into an iterable instance.*/
              Iterable<Student> students = repo.findAll();

              /* Print the values to the output from the iterable object.*/
              for (Student s : students) {
                  System.out.println("  Student: " + s);
              }

   - Using queries: Use one of these methods to run your query - The `NosqlRepository` derived queries, native queries, or using `NosqlTemplate.runQuery()`, `runQueryJavaParams()`, `runQueryNosqlParams()`.

     In following code sample, you use the derived queries to select a row from the `Student` table with the required last name and print the values to the output from the object. For more details on the derived queries, see Derived Queries.

             System.out.println("\nfindByLastName: Smith");
             /* The Student table is searched by lastname
               and an iterable instance of the Student class is returned.*/
             students = repo.findByLastName("Smith");

             /* Print the values to the output from the iterable instance.*/
             for (Student s : students) {
                 System.out.println("  Student: " + s);
             }

6. Running the program: Execute the application code samples from step 5. The Spring Data Framework adds rows to the `Student` table, searches for all the rows and prints the results to the output. It also fetches an individual row from the table.

       findAll:
         Student: Student{id=5, firstName=John, lastName=Doe}
         Student: Student{id=6, firstName=John, lastName=Smith}

       findByLastName: Smith
         Student: Student{id=6, firstName=John, lastName=Smith}

Modifying the table: To modify a table, you can use the `NosqlTemplate.runTableRequest()` method.

Note:

While the Oracle NoSQL Database SDK for Spring Data provides an option to modify the tables, it is not recommended to alter the schemas as the Spring Data Framework expects tables to comply with the default schema (two columns - the primary key column of types string, integer, long, or timestamp and a JSON column called kv_json_).