Spring Data Frameworkを使用したOracle NoSQL Databaseへのアクセス

Oracle NoSQL Database SDK for Spring Dataを使用して、SpringからOracle NoSQL Databaseにアクセスする方法について学習します。

Spring Data Frameworkを使用すると、Oracle NoSQL Databaseの非セキュアなストアとの接続を設定し、表に行を挿入してから、表からデータを取得できます。

例2-1 Spring Data Frameworkを使用したNoSQLデータベースへのアクセス

次の例は、Mavenプロジェクトを設定してから、次のクラス/インタフェースを追加する方法を示しています。
  • AppConfigクラス
  • Studentクラス
  • StudentRepositoryインタフェース
  • Appクラス

その後、Springアプリケーションを実行して必要な出力を取得します。次のステップでは、これについて詳しく説明します。

  1. Mavenプロジェクトの設定:

    必要なPOMファイルの依存性を使用して、Mavenプロジェクトを設定します。詳細は、「Oracle NoSQL Database SDK for Spring Dataについて」を参照してください。

  2. Appconfigクラスの設定:

    NosqlDbConfig Spring Beanを提供するようにAbstractNosqlConfigurationクラスを拡張するAppConfigクラスを設定します。NosqlDbConfig Spring Beanは、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;
        }
    }

    ノート:

    Oracle NoSQL Databaseセキュア・ストアへの接続の詳細は、「接続の設定」の項を参照してください。
  3. エンティティ・クラスの定義:

    新しいパッケージを作成し、次のStudentエンティティ・クラスを追加して永続させます。このエンティティ・クラスはOracle NoSQL Databaseの表を表しています。また、このエンティティのインスタンスはその表の行に対応します。

    @NosqlId注釈を指定して、idフィールドがIDとして機能し、基礎となるストレージ表の主キーになることを示し、generated=true属性を指定してこのIDをシーケンスに従って自動生成するように指定します。

    IDフィールド・タイプが文字列の場合は、UUIDが使用されます。IDフィールド・タイプがintegerまたはlongの場合は、"GENERATED ALWAYS as IDENTITY (NO CYCLE)"シーケンスが使用されます。

    すべてのSpring Dataクラス、メソッド、インタフェースおよび例の詳細は、SDK for Spring Data APIリファレンスを参照してください。

    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 +
                '}';
        }
    }

    Spring Dataアプリケーションを使用して表を作成すると、スキーマが自動的に作成され、主キー列(String、integer、longまたはtimestamp型)とkv_json_というJSON列の2つの列が含まれます。

    表がすでに存在する場合は、生成されたスキーマに準拠する必要があります。

    ノート:

    • 表レベルのTTLを設定するには、エンティティ・クラスの@NosqlTable注釈にttl()およびttlUnit()パラメータを指定します。詳細は、「TTL値の設定」を参照してください。
    • NosqlDbConfig.getDefaultCapacityMode()NosqlDbConfig.getDefaultStorageGB()NosqlDbConfig.getDefaultReadUnits()およびNosqlDbConfig.getDefaultWriteUnits()メソッドを使用して、@NosqlDbConfigインスタンスのOracle NoSQL Database Cloud Service表のデフォルトのTableLimitsを設定できます。次のコード・サンプルに示すように、capacityModereadUnitswriteUnitsおよびstorageGBフィールドを介して@NosqlTable注釈が使用されている場合は、表ごとにTableLimitsを指定することもできます。
      /* Set the TableLimits and TTL values. */
      @NosqlTable(readUnits = 50, writeUnits = 50, storageGB = 25)
  4. NosqlRepositoryを拡張するリポジトリの宣言:

    次のStudentRepositoryインタフェースを作成します。このインタフェースは、NosqlRepositoryインタフェースを拡張して、そのクラスの主キーのエンティティ・クラスとデータ型をパラメータ化された型としてNosqlRepositoryインタフェースに提供する必要があります。このNosqlRepositoryインタフェースは、データベースからデータを取得するために使用できるメソッドを備えています。

    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. アプリケーション・クラスの作成:

    Spring Data Frameworkで提供される各種インタフェースのいずれかを実装することで、必要に応じて機能をコーディングします。この例では、CommandLineRunnerインタフェースを使用して、runメソッドを実装し、mainメソッドを持つアプリケーション・コードを表示します。Spring bootアプリケーションの設定の詳細は、Spring Bootを参照してください。

    Springデータ・アプリケーションでは、@NosqlTable.autoCreateTablefalseに設定されていないかぎり、エンティティの初期化時に表がアプリケーションの開始時に自動的に作成されます。

    アプリケーション・コードを作成して、表にデータを挿入したり、表から行を読み取ったり、問合せを次のように実行できます。

    • データの追加および削除: 次のいずれかの方法を使用して、表に行を追加します。NosqlRepository.save(entity_object)saveAll(Iterable<T> iterable)またはNosqlTemplate.insert(entity)。既存の行を表から削除するには、次のいずれかの方法を使用します。NosqlRepository.deleteById()delete()deleteAll(Iterable<? extends T> entities)deleteAll()または NosqlTemplate.delete()deleteAll()deleteById()deleteInShard()を使用します。

      次のコード・サンプルでは、最初にNosqlRepository.deleteAll()メソッドを使用してStudent表から行を削除します。これにより、表がデータベースにあらかじめ存在している場合、表からすべての行が確実に削除されます。次に、NosqlRepository.save(entity_object)メソッドを使用して、表に行を追加します。2つの学生エンティティを作成して保存します。

      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);
         }
      }

      Studentエンティティ・クラスの@NosqlId注釈は、idフィールドがIDとして機能し、基礎となるストレージ表の主キーになることを指定します。残りのエンティティ・フィールド、つまり、firstNameおよびlastNameフィールドはJSON列に格納されます。

    • データの読取り: 次のいずれかの方法を使用して、表からデータを読み取ります。NosqlRepository.findById()findAllById()findAll()、またはNosqlTemplate.find()findAll()findAllById()を使用します。

      次のコード・サンプルでは、NosqlRepository.findAll()メソッドを使用して、表からすべての行を読み取ります。Student表からすべての行を選択し、反復可能なインスタンスに指定します。反復可能オブジェクトからの出力に値を出力します。

         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);
           }
    • 問合せの使用: 次のいずれかの方法を使用して、問合せを実行します。NosqlRepository導出問合せ、ネイティブ問合せ、またはNosqlTemplate.runQuery()runQueryJavaParams()runQueryNosqlParams()を使用します。

      次のコード・サンプルでは、導出問合せを使用して、必要な姓を使用してStudent表から行を選択し、オブジェクトからの出力にこの値を出力します。導出問合せの詳細は、導出問合せを参照してください。

          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. プログラムの実行: ステップ5のアプリケーション・コード・サンプルを実行します。Spring Data Frameworkは、Student表に行を追加し、すべての行を検索し、結果を出力します。また、表から個々の行をフェッチします。
    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}
表の変更: 表を変更するには、NosqlTemplate.runTableRequest()メソッドを使用します。

ノート:

Oracle NoSQL Database SDK for Spring Dataでは表を変更するオプションが提供されていますが、Spring Data Frameworkでは表がデフォルト・スキーマ(string、integer、longまたはtimestamp型の主キー列と、kv_json_と呼ばれるJSON列の2つの列)に準拠していることを想定しているため、スキーマを変更することはお薦めしません。