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_).