SpringでCassandra接続

SpringでCassandraに接続するメモ

dockerでCassandraを立ち上げる場合は[こちら](https://qiita.com/key_sleep/items/c0dcfbb39c94e8933c1a)を参考にしてください

## 依存追加

Gradle

```build.gradle
dependencies {
    implementation 'org.springframework.data:spring-data-cassandra:2.0.10.RELEASE'
}
```

Maven

```pom.xml
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-cassandra -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-cassandra</artifactId>
    <version>2.1.10.RELEASE</version>
</dependency>
```

## application.ymlの記述

```application.yml
spring:
  data:
    cassandra:
      username: user
      password: pass
      keyspaceName: test
      contactPoints: localhost
      port: 9044
```

## Configの作成

ここでbasepackageを指定することで配下のRepositoryには全てこの設定が適用される
こんな感じ
cassandra
  - Repository
  Config
  
Cassandraを二つ繋ぐ必要がある場合にはbasepackage単位で設定する

```java
@Configuration
@EnableCassandraRepositories(
        basePackages = "jp.co.sample.cassandrasample.infrastructure.cassandra.*",
        cassandraTemplateRef = "cassandraTemplate")
public class CassandraConfig extends AbstractCassandraConfiguration {

    @Value("${spring.data.cassandra.username}")
    private String username;

    @Value("${spring.data.cassandra.password}")
    private String password;

    @Value("${spring.data.cassandra.keyspaceName}")
    private String keyspaceName;

    @Value("${spring.data.cassandra.contactPoints}")
    private String contactPoints;

    @Value("${spring.data.cassandra.port}")
    private int port;

    @Override
    @Primary
    @Bean(name = "cassandraTemplate")
    public CassandraAdminTemplate cassandraTemplate() {
        return new CassandraAdminTemplate(Objects.requireNonNull(session().getObject()), cassandraConverter());
    }

    // ポート番号の設定
    @Override
    @Bean(name = "Port")
    public int getPort() {
        return port;  // デフォルトは9042
    }

    // キースペースの設定
    @Override
    @Bean(name = "KeySpace")
    protected String getKeyspaceName() {
        return keyspaceName;
    }

    /**
     * クラスタの設定
     */
    @Bean(name = "cluster")
    public CassandraClusterFactoryBean cluster() {
        CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean();
        PlainTextAuthProvider plainTextAuthProvider = new PlainTextAuthProvider(username,password);

        cluster.setContactPoints(contactPoints);
        cluster.setPort(port);
        cluster.setRetryPolicy(DefaultRetryPolicy.INSTANCE);
        cluster.setAuthProvider(plainTextAuthProvider);
        return cluster;
    }

    @Override
    @Bean(name = "Session")
    public CassandraSessionFactoryBean session() {

        CassandraSessionFactoryBean session = new CassandraSessionFactoryBean();

        session.setCluster(Objects.requireNonNull(cluster().getObject()));
        session.setConverter(cassandraConverter());
        session.setKeyspaceName(getKeyspaceName());
        session.setSchemaAction(getSchemaAction());
        session.setStartupScripts(getStartupScripts());
        session.setShutdownScripts(getShutdownScripts());

        return session;
    }

    @Override
    public QueryOptions getQueryOptions() {
        QueryOptions queryOptions = new QueryOptions();
        queryOptions.setConsistencyLevel(ConsistencyLevel.QUORUM);
        return queryOptions;
    }
}
```

## Entityの作成

```java
@AllArgsConstructor
@Data
@EqualsAndHashCode
@Table(value = "test_table")
public class TestJpaEntity {

    @PrimaryKey("id")
    private String table_id;

    private String data;

    @Column("update_time")
    private Date updateTime;

}
```


## Repositoryの作成

```java

public interface TestRepository extends CrudRepository<RecentItemJpaEntity, String> {
    List<TestJpaEntity> findAll();
}
```