使用Spring Data Cassandra动态创建键空间,表和生成表

Anu*_*Anu 11 java cassandra spring-boot spring-data-cassandra

使用Cassandra,我想使用Spring Boot应用程序动态创建键空间和表.我正在使用基于Java的配置.

我有一个用@Table注释的实体,我希望在应用程序启动之前创建它的模式,因为它具有事先已知的固定字段.

但是,根据登录用户的不同,我还想动态地为这些用户创建附加表,并能够向这些表插入条目.

有人可以引导我使用一些我可以利用的资源,或指出我如何解决这些问题.非常感谢您的帮助!

Joh*_*lum 17

最简单的方法是将Spring Boot Starter Data Cassandra依赖项添加到Spring Boot应用程序中,就像这样......

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-cassandra</artifactId>
  <version>1.3.5.RELEASE</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

此外,这将为您的应用程序添加Spring Data Cassandra 依赖项.

使用Spring Data Cassandra,您可以通过调用setKeyspaceCreations(:Set)方法使用CassandraClusterFactoryBean(或更准确地说,子类...... CassandraCqlClusterFactoryBean)配置应用程序的Keyspace .

KeyspaceActionSpecification类是不言自明.您甚至可以使用KeyspaceActionSpecificationFactoryBean创建一个,将其添加到a Set然后将其传递给该setKeyspaceCreations(..)方法CassandraClusterFactoryBean.

为了生成应用程序的表,您基本上只需要使用SD Cassandra @Table注释来注释您的应用程序域对象(实体),并确保可以在应用程序的CLASSPATH上找到您的域对象/实体.

具体来说,您可以让应用程序@Configuration类扩展SD Cassandra AbstractClusterConfiguration类.在那里,你会发现getEntityBasePackages()的String []的方法,你可以重写提供包含应用程序的域对象/实体类,SD卡珊德拉将使用该包装的位置扫描@Table域对象/实体.

@Table正确识别应用程序域对象/实体的情况下,将SD Cassandra SchemaAction设置为CREATE使用CassandraSessionFactoryBean方法setSchemaAction(:SchemaAction).这会在你的密钥空间的扫描过程中发现的所有域对象/实体创建表,提供您确定您正确的密钥空间CassandraSessionFactoryBean恰如其分.

显然,如果您的应用程序创建/使用多个Keyspace,您将需要CassandraSessionFactoryBean为每个Keyspace 创建一个单独的,为entityBasePackages配置属性设置适当的属于特定Keyspace的实体,以便在该Keyspace中创建关联的表.

现在...

对于每个用户的"附加"表,这是相当复杂和棘手的.

您可以在此处利用Spring Profiles,但是,配置文件通常仅在启动时应用.如果其他用户登录到已在运行的应用程序,则需要一种在运行时@Configuration向Spring 提供其他类的方法ApplicationContext.

您的Spring Boot应用程序可以为a注入一个引用AnnotationConfigApplicationContext,然后在登录事件上使用它,以编程方式根据登录应用程序的用户注册其他@Configuration类.你需要跟随你的register(Class...)电话ApplicationContext.refresh().

您还需要适当地处理表已存在的情况.

SD Cassandra目前不支持此功能,但有关详细信息,请参阅DATACASS-219.

从技术上讲,在运行时为所有用户创建应用程序所需的所有可能的表并使用Cassandra的安全设置来限制按角色和分配的权限的单个用户访问将简单得多.

另一种选择可能是在用户登录应用程序时根据需要创建临时Keyspace和/或表,在用户注销时删除它们.

显然,这里有很多不同的选择,它更多地归结为架构决策,权衡和考虑,然后它具有技术可行性,所以要小心.

希望这可以帮助.

干杯!


小智 9

在Spring配置类之后,如果它们不存在,则创建键空间和表.

@Configuration
public class CassandraConfig extends AbstractCassandraConfiguration {
    private static final String KEYSPACE = "my_keyspace";
    private static final String USERNAME = "cassandra";
    private static final String PASSWORD = "cassandra";
    private static final String NODES = "127.0.0.1"; // comma seperated nodes


    @Bean
    @Override
    public CassandraCqlClusterFactoryBean cluster() {
        CassandraCqlClusterFactoryBean bean = new CassandraCqlClusterFactoryBean();
        bean.setKeyspaceCreations(getKeyspaceCreations());
        bean.setContactPoints(NODES);
        bean.setUsername(USERNAME);
        bean.setPassword(PASSWORD);
        return bean;
    }

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

    @Override
    protected String getKeyspaceName() {
        return KEYSPACE;
    }

    @Override
    public String[] getEntityBasePackages() {
        return new String[]{"com.panda"};
    }


    protected List<CreateKeyspaceSpecification> getKeyspaceCreations() {
        List<CreateKeyspaceSpecification> createKeyspaceSpecifications = new ArrayList<>();
        createKeyspaceSpecifications.add(getKeySpaceSpecification());
        return createKeyspaceSpecifications;
    }

    // Below method creates "my_keyspace" if it doesnt exist.
    private CreateKeyspaceSpecification getKeySpaceSpecification() {
        CreateKeyspaceSpecification pandaCoopKeyspace = new CreateKeyspaceSpecification();
        DataCenterReplication dcr = new DataCenterReplication("dc1", 3L);
        pandaCoopKeyspace.name(KEYSPACE);
        pandaCoopKeyspace.ifNotExists(true).createKeyspace().withNetworkReplication(dcr);
        return pandaCoopKeyspace;
    }

}
Run Code Online (Sandbox Code Playgroud)