Connecting to Cassandra with Spring
使用 Spring 与 Apache Cassandra 时,第一个任务之一是通过 Spring IoC 容器创建 com.datastax.oss.driver.api.core.CqlSession
对象。您可以使用基于 Java 的 bean 元数据或基于 XML 的 bean 元数据来执行此操作。以下部分将对这些内容进行讨论。
对于那些不熟悉如何使用基于 Java 的 bean 元数据(而不是基于 XML 的元数据)配置 Spring 容器的人,请参阅参考文档 here 中的高级介绍以及详细文档https://www.iokays.com/spring-frameworkcore.html#beans-java-instantiating-container[此处]。 |
Registering a Session Instance by using Java-based Metadata
以下示例演示如何使用基于 Java 的 bean 元数据来注册 com.datastax.oss.driver.api.core.CqlSession
实例:
com.datastax.oss.driver.api.core.CqlSession
object by using Java-based bean metadata/*
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.cassandra.example;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.datastax.oss.driver.api.core.CqlSession;
// tag::class[]
@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();
}
}
// end::class[]
此方法让您可以使用您可能已知的标准 com.datastax.oss.driver.api.core.CqlSession
API。
另一种方法是使用 Spring 的 CqlSessionFactoryBean
将 com.datastax.oss.driver.api.core.CqlSession
实例注册到容器。与直接实例化 com.datastax.oss.driver.api.core.CqlSession
实例相比,FactoryBean
方法还有额外的优势,即还向容器提供一个 ExceptionTranslator
实现,该实现将 Cassandra 异常转换为 Spring 可移植 DataAccessException
层次结构中的异常。https://www.iokays.com/spring-frameworkdata-access.html[Spring 的 DAO 支持功能] 中描述了此层次结构和 @Repository
的使用。
以下示例显示了基于 Java 的工厂类用法:
CqlSessionFactoryBean
:/*
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.cassandra.example;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.config.CqlSessionFactoryBean;
// tag::class[]
@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;
}
}
// end::class[]
对对象映射和仓库支持使用 CassandraTemplate
需要一个 CassandraTemplate
、CassandraMappingContext
、CassandraConverter
以及启用的仓库支持。
以下示例显示了向对象映射注册组件以及启用仓库支持的方法:
/*
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.cassandra.example;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.SessionFactory;
import org.springframework.data.cassandra.config.CqlSessionFactoryBean;
import org.springframework.data.cassandra.config.SchemaAction;
import org.springframework.data.cassandra.config.SessionFactoryFactoryBean;
import org.springframework.data.cassandra.core.CassandraOperations;
import org.springframework.data.cassandra.core.CassandraTemplate;
import org.springframework.data.cassandra.core.convert.CassandraConverter;
import org.springframework.data.cassandra.core.convert.MappingCassandraConverter;
import org.springframework.data.cassandra.core.mapping.CassandraMappingContext;
import org.springframework.data.cassandra.core.mapping.SimpleUserTypeResolver;
import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories;
import com.datastax.oss.driver.api.core.CqlSession;
// tag::class[]
@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);
}
}
// end::class[]
创建注册 Spring Data for Apache Cassandra 组件的配置类可能是一项艰巨的挑战,因此 Spring Data for Apache Cassandra 提供了一个预建的配置支持类。从 AbstractCassandraConfiguration
扩展的类注册 Spring Data for Apache Cassandra 用 Bean。AbstractCassandraConfiguration
让你能提供各种配置选项,例如初始实体、默认查询选项、池选项、套接字选项等等。AbstractCassandraConfiguration
还支持你根据初始实体(如果有此类实体)生成模式。从 AbstractCassandraConfiguration
扩展要求你至少通过实现 getKeyspaceName
方法提供键空间名称。以下示例显示了如何使用 AbstractCassandraConfiguration
注册 Bean:
AbstractCassandraConfiguration
/*
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.cassandra.example;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.config.AbstractCassandraConfiguration;
// tag::class[]
@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";
}
}
// end::class[]
Abstract…Configuration
类为从应用程序中使用 Cassandra 连接所有必需的 Bean。此配置假设一个 CqlSession
并通过 SessionFactory
将其连接到诸如 CqlTemplate
的相关组件。如果你想自定义 CqlSession
的创建,那么你可以提供一个 SessionBuilderConfigurer
函数来自定义 CqlSessionBuilder
。这很有用,例如为 Astra 提供一个 Cloud 连接包。
AbstractCassandraConfiguration
/*
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.cassandra.example;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.config.AbstractCassandraConfiguration;
// tag::class[]
@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";
}
}
// end::class[]
XML Configuration
此部分介绍如何使用 XML 配置 Spring Data Cassandra。
虽然我们仍支持命名空间配置,但我们通常建议使用 Java-based Configuration。
Externalizing Connection Properties
要 externalize 连接属性,你应该先创建一个属性文件,其中包含连接到 Cassandra 所需的信息。contactpoints
和 keyspace
是必需字段。
以下示例显示了名为 cassandra.properties
的属性文件:
cassandra.contactpoints=10.1.55.80:9042,10.1.55.81:9042
cassandra.keyspace=showcase
在接下来的两个示例中,我们使用 Spring 将这些属性加载到 Spring 环境。
Registering a Session Instance by using XML-based Metadata
虽然你可以使用 Spring 的传统 <beans/>
XML 命名空间来向容器注册 com.datastax.oss.driver.api.core.CqlSession
的实例,但 XML 可能非常冗长,因为它很通用。XML 命名空间是配置常用对象(例如 CqlSession
实例)的更佳选择。cassandra
命名空间让你可以创建一个 CqlSession
实例。
以下示例显示了如何配置 cassandra
命名空间:
cassandra
namespace<?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 配置连接 Cassandra 是多么容易,但还有许多其他选项。基本上,DataStax Java Driver 中的任何可用的选项在 Spring Data for Apache Cassandra 配置中也可用。这包括但不限于认证、负载平衡策略、重试策略和池选项。所有 Spring Data for Apache Cassandra 方法名称和 XML 元素的命名与 Driver 上的配置选项完全相同(或尽可能接近),以便对任何现有的 Driver 配置进行映射应该是直接的。以下示例展示了如何使用 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" />