Cassandra - SpringFrameworkアプリケーション

実際に作成したサンプルは GitHub を参照のこと。

動作環境

インストール手順は、Cassandraのインストール を、キースペース、テーブルの作成は、データベースの定義 を参照すること。

また、アプリケーションの作成は、Spring Bootを利用しているため詳細は、Spring Boot を参照すること。

[OS]
MacOSX 10.9.5

[JVM]
Java(TM) SE Runtime Environment (build 1.8.0_40-b27) Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)

[Cassandraバージョン]

  • cqlsh 5.0.1
  • Cassandra 3.7
  • CQL spec 3.4.2
  • Native protocol v4
  • Cassandra driver 3.0.3

[Springバージョン]

  • Spring Boot 1.4.0.RELEASE(Spring Framework 4.3.2.RELEASE)
  • Spring Data Cassandra 1.5.0.M1

Note

2016年9月時点では、Spring Data Cassandra 1.4.3.RELEASEが最新だが、 Cassandra 2.Xのみをサポートしている。 Cassandra3.Xへの対応は Spring Data Cassandra 1.5以降を予定しているため 、Spring Data Release Train Ingalls M1を使用する。

事前準備

pom.xml設定

上述の通り、Spring Data Release Train Ingalls M1を使用するため、pom.xmlに以下の通り設定を行っておく必要がある。

  • parentとして、spring-boot-starter-parentを指定

  • Spring Milestone Repositoryを追加

  • プロパティにIngalls-M1を指定

  • Cassandra driverのバージョンを指定

  • Spring Data Cassandraに必要なライブラリを追加

    • spring-boot-starter-aop
    • spring-boot-starter-data-cassandra
    • cassandra-driver-core
    • jackson-databind
 <parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>1.4.0.RELEASE</version>
 </parent>

 <properties>
   <apt.version>1.1.3</apt.version>
   <querydsl.version>4.1.3</querydsl.version>
   <cassandra-driver.version>3.0.3</cassandra-driver.version>
   <spring-data-releasetrain.version>Ingalls-M1</spring-data-releasetrain.version>
 </properties>

 <repositories>
   <repository>
     <id>spring-milestones</id>
     <name>Spring Milestones</name>
     <url>https://repo.spring.io/libs-milestone</url>
     <snapshots>
       <enabled>false</enabled>
     </snapshots>
   </repository>
 </repositories>

 <dependencies>
   <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-aop</artifactId>
   </dependency>
   <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-cassandra</artifactId>
   </dependency>
   <dependency>
     <groupId>com.datastax.cassandra</groupId>
     <artifactId>cassandra-driver-core</artifactId>
   </dependency>
   <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-test</artifactId>
     <scope>test</scope>
   </dependency>
   <dependency>
     <groupId>com.fasterxml.jackson.core</groupId>
     <artifactId>jackson-databind</artifactId>
   </dependency>
</dependencies>

Note

公式の Spring Data Examples もあわせて適宜参考にすること。

キースペース、テーブル、データ設定

アクセスするCassandraの環境を事前に構築しておく。ここでは、テーブル構築とデータ設定は別ファイルchema.sql、data.sqlに切り出しておき、Cassandraに接続後、キースペースを作成して、データ設定を行う。

schema.cql
USE sample;

DROP TABLE IF EXISTS users;

CREATE TABLE users (
        user_id bigint,
        user_name text,
        first_name text,
        last_name text,
        PRIMARY KEY (user_id)
    );
data.cql
USE sample;

INSERT INTO users JSON '{"user_id": 0, "user_name": "org.debugroom", "first_name": "org", "last_name": "debugroom" }' IF NOT EXISTS ;
INSERT INTO users JSON '{"user_id": 1, "user_name": "(ΦωΦ)", "first_name": "(・∀・)", "last_name": "(・ω・`)" }' IF NOT EXISTS ;

cqlshを起動して、データ設定を行う。

cqlsh localhost 9042

cqlsh> CREATE KEYSPACE sample WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};

cqlsh> source 'schema.cql'

calsh> source 'data.cql'

アプリケーションの作成

作成したテーブルに対応するエンティティクラスを作成する。

package org.debugroom.sample.cassandra.entity;

import lombok.Data;
import lombok.NoArgsConstructor;

import org.springframework.data.cassandra.mapping.Column;
import org.springframework.data.cassandra.mapping.PrimaryKey;
import org.springframework.data.cassandra.mapping.Table;

@Data
@NoArgsConstructor
@Table("users")
public class User {

        @PrimaryKey("user_id") private Long userId;

        @Column("user_name") private String userName;
        @Column("first_name") private String firstName;
        @Column("last_name") private String lastName;

        public User(Long userId) {
            this.setUserId(userId);
        }
}

Repositoryクラスを作成する。

package org.debugroom.sample.cassandra.repository;

import org.springframework.data.repository.CrudRepository;

import org.debugroom.sample.cassandra.entity.User;

public interface UserRepository extends CrudRepository<User, Long>{
}

Serviceインターフェース及び、実装クラスを作成する。

package org.debugroom.sample.cassandra.service;

import java.util.List;

import org.debugroom.sample.cassandra.entity.User;

public interface SampleService {

    public List<User> getUsers();

}
package org.debugroom.sample.cassandra.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import org.debugroom.sample.cassandra.entity.User;
import org.debugroom.sample.cassandra.repository.UserRepository;

@Service("sampleService")
public class SampleServiceImpl implements SampleService{

    @Autowired
    UserRepository userRepository;

    @Override
    public List<User> getUsers() {
        Iterable<User> users = userRepository.findAll();
        return (List<User>)users;
    }

}

コンフィグレーション及びアプリケーション実行クラスを作成する。

package org.debugroom.sample.cassandra.config;

import com.datastax.driver.core.Session;

import java.util.List;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.config.SchemaAction;
import org.springframework.data.cassandra.config.java.AbstractCassandraConfiguration;
import org.springframework.data.cassandra.core.CassandraTemplate;
import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories;

import org.debugroom.sample.cassandra.entity.User;
import org.debugroom.sample.cassandra.service.SampleService;
import org.debugroom.sample.cassandra.service.SampleServiceImpl;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
@EnableAutoConfiguration
public class SimpleApp {

    public static void main(String[] args){
        ConfigurableApplicationContext context = new SpringApplicationBuilder(
                             SimpleApp.class).web(false).run(args);
        SampleService sampleService = context.getBean(SampleService.class);
        List<User> users = sampleService.getUsers();
        log.info(SimpleApp.class.getName() + " : users ");
        for(User user : users){
            log.info(SimpleApp.class.getName() + " :     - " + user.toString());
        }
     }

     @Bean SampleService sampleService(){
         return new SampleServiceImpl();
     }

     @ComponentScan
     @Configuration
     @EnableCassandraRepositories("org.debugroom.sample.cassandra.repository")
     static class CassandraConfig extends AbstractCassandraConfiguration{

         @Override
         protected String getKeyspaceName() {
             return "sample";
         }

         @Override
         public String[] getEntityBasePackages() {
             return new String[] { "org.debugroom.sample.cassandra.entity" };
         }

         @Override
         public SchemaAction getSchemaAction() {
             return SchemaAction.CREATE_IF_NOT_EXISTS;
         }

         @Bean
         public CassandraTemplate cassandraTemplate(Session session){
             return new CassandraTemplate(session);
         }

     }
}

Todo

Spring Data CassandraのEntity、Repository、Configurationクラスのオプションを整理。

Spring Data Cassandraのサポート

Spring Data Cassandraのサポート内容を公式ページから直訳すると以下の通りである。

  • Cassandra Driverインスタンスや、レプリカセットの設定のためのJavaConfig及びXML定義のSpring設定のサポート
  • 共通的なCassandraオペレーションの処理生産性向上させるCassandraTemplateのヘルパークラス及び、CQL TableとPOJOのマッピング
  • Springの統合的な例外ヒエラルキーへの例外の変換
  • SpringのCoversionServiceと統合したリッチなオブジェクトマッピング
  • アノテーションをベースとしたメタデータのマッピングと他のメタデータフォーマットをサポートするための拡張
  • 永続化とライフサイクルイベントへのマッピング
  • Javaベースのクエリ、クライテリア、更新DSL
  • カスタムファインダーメソッドのサポートを含むRepositoryインターフェースの自動実装

より意訳的に、Spring Data Cassandraが提供するメリットの内容としては、以下の通りである。

  • Cassandraへのデータアクセスするためのボイラープレートコードの隠蔽。
  • Spring Frameworkとの統合、依存性の注入によるCassandaTemplateクラスの提供。
  • エンティティクラスアノテーションによるオブジェクトマッピング機能
  • 設定クラスによるAP起動時のCassandraテーブル構築オプションの提供
  • CrudRepositoryの継承インターフェースによる基本的なデータアクセスコード実装量の軽減
  • メソッド命名規約によるCQL自動組み立てによるコード実装量の軽減
  • Spring Data のRepositoryCustomやResultsetExecutorによる拡張性の保持
  • SrpngのDataアクセス例外を提供することによる、サービスロジックの抽象化による差分の隠蔽。