使用 Spring 连接 Cassandra

在 Spring 中使用 Apache Cassandra 时,首要任务之一是通过 Spring IoC 容器创建一个 com.datastax.oss.driver.api.core.CqlSession 对象。 您可以使用基于 Java 的 Bean 元数据,也可以使用基于 XML 的 Bean 元数据来实现这一点。 以下章节将对此进行讨论。spring-doc.cadn.net.cn

对于那些不熟悉如何使用基于 Java 的 Bean 元数据(而非基于 XML 的元数据)来配置 Spring 容器的用户,请参阅参考文档中的此处的高级介绍,以及此处的详细文档。

使用基于 Java 的元数据注册会话实例

以下示例展示了如何使用基于 Java 的 bean 元数据来注册一个 com.datastax.oss.driver.api.core.CqlSession 实例:spring-doc.cadn.net.cn

示例 1. 使用基于 Java 的 Bean 元数据注册一个 com.datastax.oss.driver.api.core.CqlSession 对象
@Configuration
public class AppConfig {

	/*
	 * Use the standard Cassandra driver API to create a com.datastax.oss.driver.api.core.CqlSession instance.
	 */
	public @Bean CqlSession session() {
		return CqlSession.builder().withKeyspace("mykeyspace").build();
	}
}

这种方法允许您使用您可能已经熟悉的标准化 com.datastax.oss.driver.api.core.CqlSession API。spring-doc.cadn.net.cn

另一种方法是使用 Spring 的 com.datastax.oss.driver.api.core.CqlSession 向容器注册一个 CqlSessionFactoryBean 实例。 与直接实例化 com.datastax.oss.driver.api.core.CqlSession 相比,使用 FactoryBean 的方式还额外提供了一个 ExceptionTranslator 实现,该实现可将 Cassandra 异常转换为 Spring 可移植的 DataAccessException 异常体系中的异常。 该异常体系以及 @Repository 注解的使用在Spring 的 DAO 支持特性中有详细说明。spring-doc.cadn.net.cn

以下示例展示了基于 Java 的工厂类用法:spring-doc.cadn.net.cn

示例2. 使用 Spring 的 CqlSessionFactoryBean 注册一个 com.datastax.oss.driver.api.core.CqlSession 对象:
@Configuration
public class FactoryBeanAppConfig {

	/*
	 * Factory bean that creates the com.datastax.oss.driver.api.core.CqlSession instance
	 */
	@Bean
	public CqlSessionFactoryBean session() {

		CqlSessionFactoryBean session = new CqlSessionFactoryBean();
		session.setContactPoints("localhost");
		session.setKeyspaceName("mykeyspace");

		return session;
	}
}

使用带有对象映射和仓库支持的 CassandraTemplate 需要一个 CassandraTemplateCassandraMappingContextCassandraConverter,并启用仓库支持。spring-doc.cadn.net.cn

以下示例展示了如何注册组件以配置对象映射和仓库支持:spring-doc.cadn.net.cn

示例 3. 注册组件以配置对象映射和仓库支持
@Configuration
@EnableCassandraRepositories(basePackages = { "org.springframework.data.cassandra.example" })
public class CassandraConfig {

	@Bean
	public CqlSessionFactoryBean session() {

		CqlSessionFactoryBean session = new CqlSessionFactoryBean();
		session.setContactPoints("localhost");
		session.setKeyspaceName("mykeyspace");

		return session;
	}

	@Bean
	public SessionFactoryFactoryBean sessionFactory(CqlSession session, CassandraConverter converter) {

		SessionFactoryFactoryBean sessionFactory = new SessionFactoryFactoryBean();
		sessionFactory.setSession(session);
		sessionFactory.setConverter(converter);
		sessionFactory.setSchemaAction(SchemaAction.NONE);

		return sessionFactory;
	}

	@Bean
	public CassandraMappingContext mappingContext() {
		return new CassandraMappingContext();
	}

	@Bean
	public CassandraConverter converter(CqlSession cqlSession, CassandraMappingContext mappingContext) {

		MappingCassandraConverter cassandraConverter = new MappingCassandraConverter(mappingContext);
		cassandraConverter.setUserTypeResolver(new SimpleUserTypeResolver(cqlSession));

		return cassandraConverter;
	}

	@Bean
	public CassandraOperations cassandraTemplate(SessionFactory sessionFactory, CassandraConverter converter) {
		return new CassandraTemplate(sessionFactory, converter);
	}
}

创建用于注册 Spring Data for Apache Cassandra 组件的配置类可能是一项繁重的挑战,因此 Spring Data for Apache Cassandra 提供了一个预构建的配置支持类。 继承自 AbstractCassandraConfiguration 的类会注册供 Spring Data for Apache Cassandra 使用的 Bean。 AbstractCassandraConfiguration 允许您提供各种配置选项,例如初始实体、默认查询选项、连接池选项、套接字选项等等。AbstractCassandraConfiguration 还可在您提供初始实体的情况下,协助您基于这些实体生成数据库模式(schema)。 继承 AbstractCassandraConfiguration 至少需要您通过实现 getKeyspaceName 方法来提供 keyspace 名称。 以下示例展示了如何使用 AbstractCassandraConfiguration 注册 Bean:spring-doc.cadn.net.cn

示例 4. 使用 AbstractCassandraConfiguration 注册 Spring Data for Apache Cassandra 的 Bean
@Configuration
public class CassandraConfiguration extends AbstractCassandraConfiguration {

	/*
	 * Provide a contact point to the configuration.
	 */
	@Override
	public String getContactPoints() {
		return "localhost";
	}

	/*
	 * Provide a keyspace name to the configuration.
	 */
	@Override
	public String getKeyspaceName() {
		return "mykeyspace";
	}
}

Abstract…Configuration 类会为您应用程序中使用 Cassandra 所需的所有必要 Bean 进行装配。 该配置假定使用单个 CqlSession,并通过 SessionFactory 将其注入到相关组件(例如 CqlTemplate)中。 如果您希望自定义 CqlSession 的创建过程,可以提供一个 SessionBuilderConfigurer 函数来定制 CqlSessionBuilder。 例如,这在提供 Astra 的云连接捆绑包(Cloud Connection Bundle)时非常有用。spring-doc.cadn.net.cn

示例 5. 通过 AbstractCassandraConfiguration 连接到 Astra
@Configuration
public class CustomizedCassandraConfiguration extends AbstractCassandraConfiguration {

	/*
	 * Customize the CqlSession through CqlSessionBuilder.
	 */
	@Override
	protected SessionBuilderConfigurer getSessionBuilderConfigurer() {

		Path connectBundlePath = …;

		return builder -> builder
				.withCloudSecureConnectBundle(Path.of(connectBundlePath));
	}

	/*
	 * Provide a keyspace name to the configuration.
	 */
	@Override
	public String getKeyspaceName() {
		return "mykeyspace";
	}

}

XML 配置

本节介绍如何使用 XML 配置 Spring Data Cassandra。spring-doc.cadn.net.cn

虽然我们仍然支持命名空间配置,但我们通常建议使用基于 Java 的配置

外部化连接属性

要外部化连接属性,您应首先创建一个属性文件,其中包含连接到 Cassandra 所需的信息。contactpointskeyspace 是必填字段。spring-doc.cadn.net.cn

以下示例展示了我们的属性文件,名为 cassandra.propertiesspring-doc.cadn.net.cn

cassandra.contactpoints=10.1.55.80:9042,10.1.55.81:9042
cassandra.keyspace=showcase

在接下来的两个示例中,我们使用 Spring 将这些属性加载到 Spring 上下文中。spring-doc.cadn.net.cn

使用基于 XML 的元数据注册会话实例

虽然你可以使用 Spring 传统的 <beans/> XML 命名空间向容器注册一个 com.datastax.oss.driver.api.core.CqlSession 实例,但由于该命名空间是通用目的的,所生成的 XML 代码可能会相当冗长。 XML 命名空间是配置常用对象(例如 CqlSession 实例)的一种更好的替代方案。 cassandra 命名空间允许你创建一个 CqlSession 实例。spring-doc.cadn.net.cn

以下示例展示了如何配置 cassandra 命名空间:spring-doc.cadn.net.cn

示例 6. 使用 cassandra 命名空间通过 XML schema 配置 Cassandra
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:cassandra="http://www.springframework.org/schema/data/cassandra"
  xsi:schemaLocation="
    http://www.springframework.org/schema/data/cassandra
    https://www.springframework.org/schema/data/cassandra/spring-cassandra.xsd
    http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd">

  <!-- Default bean name is 'cassandraSession' -->
  <cassandra:session contact-points="localhost" port="9042">
    <cassandra:keyspace action="CREATE_DROP" name="mykeyspace" />
  </cassandra:session>

  <cassandra:session-factory>
    <cassandra:script
            location="classpath:/org/springframework/data/cassandra/config/schema.cql"/>
  </cassandra:session-factory>
</beans>

下面展示了用于更高级 Cassandra 配置的 XML 配置元素。 这些元素均使用默认的 bean 名称,以保持配置代码简洁易读。spring-doc.cadn.net.cn

虽然前面的示例展示了如何轻松配置 Spring 以连接 Cassandra,但还有许多其他选项可用。 基本上,DataStax Java Driver 提供的任何选项在 Spring Data for Apache Cassandra 的配置中也同样可用。 这包括但不限于身份验证、负载均衡策略、重试策略和连接池选项。 Spring Data for Apache Cassandra 的所有方法名和 XML 元素名称都与驱动程序中的配置选项完全相同(或尽可能接近),因此映射任何现有的驱动程序配置都应十分直接。 以下示例展示了如何使用 XML 配置 Spring Data 组件。spring-doc.cadn.net.cn

示例 7. 使用 XML 配置 Spring Data 组件
<!-- Loads the properties into the Spring Context and uses them to fill
in placeholders in the bean definitions -->
<context:property-placeholder location="classpath:cassandra.properties" />

<!-- REQUIRED: The Cassandra Session -->
<cassandra:session contact-points="${cassandra.contactpoints}" keyspace-name="${cassandra.keyspace}" />

<!-- REQUIRED: The default Cassandra mapping context used by `CassandraConverter` -->
<cassandra:mapping>
  <cassandra:user-type-resolver keyspace-name="${cassandra.keyspace}" />
</cassandra:mapping>

<!-- REQUIRED: The default Cassandra converter used by `CassandraTemplate` -->
<cassandra:converter />

<!-- REQUIRED: The Cassandra template is the foundation of all Spring
Data Cassandra -->
<cassandra:template id="cassandraTemplate" />

<!-- OPTIONAL: If you use Spring Data for Apache Cassandra repositories, add
your base packages to scan here -->
<cassandra:repositories base-package="org.spring.cassandra.example.repo" />