对于最新的稳定版本,请使用 Spring Data Cassandra 4.3.1Spring中文文档

对于最新的稳定版本,请使用 Spring Data Cassandra 4.3.1Spring中文文档

该类(及其反应式变体)位于软件包中,是 Spring 的 Cassandra 支持中的核心类,它提供了丰富的功能集来与数据库进行交互。 该模板提供了创建、更新、删除和查询 Cassandra 的便捷操作,并提供域对象与 Cassandra 表中的行之间的映射。CassandraTemplateReactiveCassandraTemplateorg.springframework.data.cassandraSpring中文文档

配置完成后,模板实例是线程安全的,可以在多个实例之间重复使用。

Cassandra 中的行和应用程序域类之间的映射是通过委托给接口的实现来完成的。 Spring 提供了一个默认的实现,但您也可以编写自己的自定义转换器。 有关更多详细信息,请参阅有关 Cassandra 转换的部分。CassandraConverterMappingCassandraConverterSpring中文文档

该类实现接口,其反应式变体实现 。 在尽可能的情况下,这些方法都以 Cassandra 中可用的方法命名,以使已经熟悉 Cassandra 的开发人员熟悉 API。CassandraTemplateCassandraOperationsReactiveCassandraTemplateReactiveCassandraOperations[Reactive]CassandraOperationsSpring中文文档

例如,您可以找到 、 、 和 等方法。 设计目标是尽可能轻松地在基本 Cassandra 驱动程序的使用和 . 这两个 API 之间的主要区别在于可以传递域对象,而不是 CQL 和查询对象。selectinsertdeleteupdate[Reactive]CassandraOperationsCassandraOperationsSpring中文文档

引用实例上的操作的首选方法是通过接口。[Reactive]CassandraTemplate[Reactive]CassandraOperations

使用的默认转换器实现是 。 虽然可以使用其他元数据来指定对象到行的映射,但它也可以通过使用字段和表名映射的一些约定来转换不包含其他元数据的对象。 这些约定以及映射注释的使用在“映射”一章中进行了解释。[Reactive]CassandraTemplateMappingCassandraConverterMappingCassandraConverterSpring中文文档

另一个核心特性是将 Cassandra Java 驱动程序中抛出的异常转换为 Spring 的可移植数据访问异常层次结构。 有关详细信息,请参阅有关异常翻译的部分。[Reactive]CassandraTemplateSpring中文文档

模板 API 具有不同的执行模型风格。 基本使用阻塞(命令式同步)执行模型。 您可以用于异步执行和与实例的同步,也可以用于响应式执行。CassandraTemplateAsyncCassandraTemplateListenableFutureReactiveCassandraTemplate
配置完成后,模板实例是线程安全的,可以在多个实例之间重复使用。
引用实例上的操作的首选方法是通过接口。[Reactive]CassandraTemplate[Reactive]CassandraOperations
模板 API 具有不同的执行模型风格。 基本使用阻塞(命令式同步)执行模型。 您可以用于异步执行和与实例的同步,也可以用于响应式执行。CassandraTemplateAsyncCassandraTemplateListenableFutureReactiveCassandraTemplate

实例化CassandraTemplate

CassandraTemplate应该始终配置为 Spring Bean,尽管我们之前展示了一个示例,您可以在其中直接实例化它。 但是,由于我们假设了制作 Spring 模块的上下文,因此我们假设存在 Spring 容器。Spring中文文档

有两种方法可以获得 ,具体取决于您加载 Spring 的方式:CassandraTemplateApplicationContextSpring中文文档

自动接线

您可以将 a 自动连接到您的项目中,如以下示例所示:[Reactive]CassandraOperationsSpring中文文档

@Autowired
private CassandraOperations cassandraOperations;
@Autowired
private ReactiveCassandraOperations reactiveCassandraOperations;

与所有 Spring 自动接线一样,这假设 . 如果您有多个 Bean(如果您在同一项目中使用多个键空间,则就是这种情况),那么您可以使用注释来指定要自动连接的 Bean。[Reactive]CassandraOperationsApplicationContext[Reactive]CassandraTemplate@QualifierSpring中文文档

@Autowired
@Qualifier("keyspaceOneTemplateBeanId")
private CassandraOperations cassandraOperations;
@Autowired
@Qualifier("keyspaceOneTemplateBeanId")
private ReactiveCassandraOperations reactiveCassandraOperations;

Bean 查找ApplicationContext

您还可以从 中查找 bean,如以下示例所示:[Reactive]CassandraTemplateApplicationContextSpring中文文档

CassandraOperations cassandraOperations = applicationContext.getBean("cassandraTemplate", CassandraOperations.class);
ReactiveCassandraOperations cassandraOperations = applicationContext.getBean("ReactiveCassandraOperations", ReactiveCassandraOperations.class);

查询行

可以使用 和 类来表示查询,这些类具有反映本机 Cassandra 谓词运算符名称的方法名称,例如 、 、 等。QueryCriterialtlteisSpring中文文档

and 类遵循流畅的 API 样式,因此您可以轻松地将多个方法条件和查询链接在一起,同时具有易于理解的代码。 Java 在创建和实例时使用静态导入以提高可读性。QueryCriteriaQueryCriteriaSpring中文文档

查询表中的行

在前面的章节中,我们了解了如何使用 on 上的方法检索单个对象。 这样做将返回单个域对象。 我们还可以查询要作为域对象列表返回的行集合。 假设我们有许多对象,其名称和年龄值存储在表中的行中,并且每个人都有一个帐户余额,我们现在可以使用以下代码运行查询:selectOneById[Reactive]CassandraTemplatePersonSpring中文文档

查询行[Reactive]CassandraTemplate
import static org.springframework.data.cassandra.core.query.Criteria.where;
import static org.springframework.data.cassandra.core.query.Query.query;

…

List<Person> result = cassandraTemplate.select(query(where("age").is(50))
  .and(where("balance").gt(1000.00d)).withAllowFiltering(), Person.class);
import static org.springframework.data.cassandra.core.query.Criteria.where;
import static org.springframework.data.cassandra.core.query.Query.query;

…

Flux<Person> result = reactiveCassandraTemplate.select(query(where("age").is(50))
  .and(where("balance").gt(1000.00d)).withAllowFiltering(), Person.class);

、 和 方法将对象作为参数。 此对象定义用于执行查询的条件和选项。 该条件是通过使用具有名为实例化新对象的静态工厂方法的对象指定的。 建议对 和 使用静态导入,以使查询更具可读性。selectselectOnestreamQueryCriteriawhereCriteriaorg.springframework.data.cassandra.core.query.Criteria.whereQuery.querySpring中文文档

此查询应返回满足指定条件的对象列表。 该类具有以下方法,这些方法对应于 Apache Cassandra 中提供的运算符:PersonCriteriaSpring中文文档

Criteria 类的方法

  • CriteriaDefinition gt :使用运算符创建条件。(Object value)>Spring中文文档

  • CriteriaDefinition gte :使用运算符创建条件。(Object value)>=Spring中文文档

  • CriteriaDefinition in : 通过使用 varargs 参数的运算符创建条件。(Object…​ values)INSpring中文文档

  • CriteriaDefinition in :通过使用集合的运算符创建条件。(Collection<?> collection)INSpring中文文档

  • CriteriaDefinition is :使用字段匹配 () 创建条件。(Object value)column = valueSpring中文文档

  • CriteriaDefinition lt :使用运算符创建条件。(Object value)<Spring中文文档

  • CriteriaDefinition lte :使用运算符创建条件。(Object value)Spring中文文档

  • CriteriaDefinition like :使用运算符创建条件。(Object value)LIKESpring中文文档

  • CriteriaDefinition contains :使用运算符创建条件。(Object value)CONTAINSSpring中文文档

  • CriteriaDefinition containsKey :使用运算符创建条件。(Object key)CONTAINS KEYSpring中文文档

Criteria创建后不可变。Spring中文文档

Query 类的方法

该类具有一些可用于提供查询选项的其他方法:QuerySpring中文文档

  • Query by :用于创建对象。(CriteriaDefinition…​ criteria)QuerySpring中文文档

  • Query :用于向查询添加其他条件。(CriteriaDefinition criteria)Spring中文文档

  • Query columns :用于定义要包含在查询结果中的列。(Columns columns)Spring中文文档

  • Query limit :用于将返回结果的大小限制在规定的限制范围内(用于限制)。(Limit limit)SELECTSpring中文文档

  • Query limit :用于将返回结果的大小限制在规定的限制范围内(用于限制)。(long limit)SELECTSpring中文文档

  • Query pageRequest:用于将 、 和 与查询关联(用于分页)。(Pageable pageRequest)SortPagingStatefetchSizeSpring中文文档

  • Query pagingState :用于将 a 与查询关联(用于分页)。(ByteBuffer pagingState)ByteBufferSpring中文文档

  • Query queryOptions :用于与查询关联。(QueryOptions queryOptions)QueryOptionsSpring中文文档

  • Query sort :用于为结果提供排序定义。(Sort sort)Spring中文文档

  • Query withAllowFiltering :用于呈现查询。()ALLOW FILTERINGSpring中文文档

Query创建后不可变。 调用方法会创建新的不可变(中间)对象。QuerySpring中文文档

查询行的方法

该类具有以下返回行的方法:QuerySpring中文文档

  • List<T> select :从表中查询对象类型的列表。(Query query, Class<T> entityClass)TSpring中文文档

  • T selectOne :从表中查询单个类型的对象。(Query query, Class<T> entityClass)TSpring中文文档

  • Slice<T> slice :通过从表中查询 of 类型的对象来启动或继续分页。(Query query, Class<T> entityClass)SliceTSpring中文文档

  • Stream<T> stream :从表中查询类型对象的流。(Query query, Class<T> entityClass)TSpring中文文档

  • List<T> select :通过提供 CQL 语句,对表中类型的对象列表进行临时查询。(String cql, Class<T> entityClass)TSpring中文文档

  • T selectOne:通过提供 CQL 语句对表中的单个对象类型进行临时查询。(String cql, Class<T> entityClass)TSpring中文文档

  • Stream<T> stream :通过提供 CQL 语句从表中查询类型对象流的临时查询。(String cql, Class<T> entityClass)TSpring中文文档

查询方法必须指定返回的目标类型。TSpring中文文档

Fluent 模板 API

当涉及到与 Apache Cassandra 的更多低级交互时,接口是核心组件之一。 它提供了广泛的方法。 您可以为每种方法找到多个重载。 它们中的大多数都涵盖了 API 的可选(可为 null)部分。[Reactive]CassandraOperationsSpring中文文档

FluentCassandraOperations其反应式变体为提供更易读、更流畅的 API 的常用方法提供了更窄的接口。 入口点 (、 、 和 ) 遵循基于要执行的操作的自然命名方案。 从入口点开始,API 旨在仅提供与上下文相关的方法,这些方法引导开发人员使用调用实际 . 以下示例显示了 Fluent API:ReactiveFluentCassandraOperations[Reactive]CassandraOperationsquery(…)insert(…)update(…)delete(…)[Reactive]CassandraOperationsSpring中文文档

List<SWCharacter> all = ops.query(SWCharacter.class)
  .inTable("star_wars")                        (1)
  .all();
1 如果使用定义表名或使用类名作为表名不是问题,请跳过此步骤SWCharacter@Table
Flux<SWCharacter> all = ops.query(SWCharacter.class)
  .inTable("star_wars")                        (1)
  .all();
1 如果使用定义表名或使用类名作为表名不是问题,请跳过此步骤SWCharacter@Table

如果 Cassandra 中的表包含不同类型的实体,例如 的 表内的实体,则可以使用不同的类型来映射查询结果。 您可以使用将结果映射到不同的目标类型,同时仍适用于查询和表名。 下面的示例使用 and 方法:JediSWCharactersas(Class<?> targetType)query(Class<?> entityType)queryasSpring中文文档

List<Jedi> all = ops.query(SWCharacter.class)    (1)
  .as(Jedi.class)                                (2)
  .matching(query(where("jedi").is(true)))
  .all();
1 查询字段将针对类型进行映射。SWCharacter
2 生成的行将映射到 .Jedi
Flux<Jedi> all = ops.query(SWCharacter.class)    (1)
  .as(Jedi.class)                                (2)
  .matching(query(where("jedi").is(true)))
  .all();
1 查询字段将针对类型进行映射。SWCharacter
2 生成的行将映射到 .Jedi
通过仅提供 类型 到 ,可以直接将投影应用于生成的文档。interfaceas(Class<?>)

终止方法 (、 、 和 ) 处理检索单个实体和检索多个实体作为 或 和类似操作之间的切换。first()one()all()stream()ListStreamSpring中文文档

新的 Fluent 模板 API 方法(即 、 、 和 )有效地使用线程安全支持对象来编写 CQL 语句。 但是,它以额外的年轻一代 JVM 堆开销为代价,因为设计基于各种 CQL 语句组件的最终字段和基于突变的构造。 在可能插入或删除大量对象(例如,在循环内部)时,您应该小心。query(..)insert(..)update(..)delete(..)
1 如果使用定义表名或使用类名作为表名不是问题,请跳过此步骤SWCharacter@Table
1 如果使用定义表名或使用类名作为表名不是问题,请跳过此步骤SWCharacter@Table
1 查询字段将针对类型进行映射。SWCharacter
2 生成的行将映射到 .Jedi
1 查询字段将针对类型进行映射。SWCharacter
2 生成的行将映射到 .Jedi
通过仅提供 类型 到 ,可以直接将投影应用于生成的文档。interfaceas(Class<?>)
新的 Fluent 模板 API 方法(即 、 、 和 )有效地使用线程安全支持对象来编写 CQL 语句。 但是,它以额外的年轻一代 JVM 堆开销为代价,因为设计基于各种 CQL 语句组件的最终字段和基于突变的构造。 在可能插入或删除大量对象(例如,在循环内部)时,您应该小心。query(..)insert(..)update(..)delete(..)

保存、更新和删除行

[Reactive]CassandraTemplate提供了一种保存、更新和删除域对象并将这些对象映射到 Cassandra 中管理的表的简单方法。Spring中文文档

类型映射

Spring Data for Apache Cassandra 依靠 DataStax Java 驱动程序来确保类型支持。 添加或更改类型时,Spring Data for Apache Cassandra 模块将继续运行,而无需更改。 有关当前类型映射矩阵,请参阅 CQL 数据类型和“数据映射和类型转换”。CodecRegistrySpring中文文档

插入和更新行的方法

[Reactive]CassandraTemplate有几种方便的方法来保存和插入对象。 为了对转换过程进行更精细的控制,您可以将 Spring 实例注册到 (例如,)。ConverterMappingCassandraConverterConverter<Row, Person>Spring中文文档

插入操作和更新操作之间的区别在于,操作不插入值。INSERTnull

使用该操作的简单情况是保存 POJO。 在这种情况下,表名由简单类名(而不是完全限定的类名)确定。 可以使用映射元数据覆盖用于存储对象的表。INSERTSpring中文文档

插入或更新时,必须设置该属性。 Apache Cassandra 无法生成 ID。idSpring中文文档

以下示例使用 save 操作并检索其内容:Spring中文文档

使用[Reactive]CassandraTemplate
import static org.springframework.data.cassandra.core.query.Criteria.where;
import static org.springframework.data.cassandra.core.query.Query.query;
…

Person bob = new Person("Bob", 33);
cassandraTemplate.insert(bob);

Person queriedBob = cassandraTemplate.selectOneById(query(where("age").is(33)), Person.class);
import static org.springframework.data.cassandra.core.query.Criteria.where;
import static org.springframework.data.cassandra.core.query.Query.query;
…

Person bob = new Person("Bob", 33);
cassandraTemplate.insert(bob);

Mono<Person> queriedBob = reactiveCassandraTemplate.selectOneById(query(where("age").is(33)), Person.class);

您可以使用以下操作进行插入和保存:Spring中文文档

  • void insert :在 Apache Cassandra 表中插入对象。(Object objectToSave)Spring中文文档

  • WriteResult insert :将对象插入 Apache Cassandra 表并应用 .(Object objectToSave, InsertOptions options)InsertOptionsSpring中文文档

您可以使用以下更新操作:Spring中文文档

  • void update :更新 Apache Cassandra 表中的对象。(Object objectToSave)Spring中文文档

  • WriteResult update :更新 Apache Cassandra 表中的对象并应用 .(Object objectToSave, UpdateOptions options)UpdateOptionsSpring中文文档

您还可以使用老式方法编写自己的 CQL 语句,如以下示例所示:Spring中文文档

String cql = "INSERT INTO person (age, name) VALUES (39, 'Bob')";

cassandraTemplate().getCqlOperations().execute(cql);
String cql = "INSERT INTO person (age, name) VALUES (39, 'Bob')";

Mono<Boolean> applied = reactiveCassandraTemplate.getReactiveCqlOperations().execute(cql);

您还可以配置其他选项,例如 TTL、一致性级别和轻量级事务,当使用 和 时。InsertOptionsUpdateOptionsSpring中文文档

我的行插入到哪个表中?

您可以通过两种方式管理用于对表进行操作的表名。 默认表名是更改为以小写字母开头的简单类名。 因此,该类的实例将存储在表中。 第二种方法是在注释中指定表名。com.example.Personperson@TableSpring中文文档

在批处理中插入、更新和删除单个对象

Cassandra 协议支持使用批处理在一个操作中插入行集合。Spring中文文档

接口中的以下方法支持此功能:[Reactive]CassandraTemplateSpring中文文档

  • batchOps:创建一个新文件来填充批处理。[Reactive]CassandraBatchOperationsSpring中文文档

[Reactive]CassandraBatchOperationsSpring中文文档

更新表中的行

对于更新,您可以选择更新多行。Spring中文文档

以下示例演示如何通过向分配余额添加一次性 50.00 美元的奖金来更新单个帐户对象:+Spring中文文档

使用[Reactive]CasandraTemplate
import static org.springframework.data.cassandra.core.query.Criteria.where;
import org.springframework.data.cassandra.core.query.Query;
import org.springframework.data.cassandra.core.query.Update;

…

boolean applied = cassandraTemplate.update(Query.query(where("id").is("foo")),
  Update.create().increment("balance", 50.00), Account.class);
import static org.springframework.data.cassandra.core.query.Criteria.where;
import org.springframework.data.cassandra.core.query.Query;
import org.springframework.data.cassandra.core.query.Update;

…

Mono<Boolean> wasApplied = reactiveCassandraTemplate.update(Query.query(where("id").is("foo")),
  Update.create().increment("balance", 50.00), Account.class);

除了前面讨论的内容之外,我们还使用对象提供更新定义。 该类具有与可用于 Apache Cassandra 的更新分配匹配的方法。QueryUpdateUpdateSpring中文文档

大多数方法返回对象,以提供用于代码样式的流畅 API。UpdateSpring中文文档

执行行更新的方法

update 方法可以更新行,如下所示:Spring中文文档

  • boolean update :更新 Apache Cassandra 表中的一系列对象。(Query query, Update update, Class<?> entityClass)Spring中文文档

Update 类的方法

该类可以与一点“语法糖”一起使用,因为它的方法是链接在一起的。 此外,您还可以使用 static 方法和静态导入启动新实例的创建。UpdateUpdatepublic static Update update(String key, Object value)Spring中文文档

该类具有以下方法:UpdateSpring中文文档

  • AddToBuilder addTo 入口点:(String columnName)AddToBuilderSpring中文文档

    • 更新:使用更新分配将集合值预置到现有集合。prepend(Object value)+Spring中文文档

    • 更新:使用更新分配将所有集合值附加到现有集合之前。prependAll(Object…​ values)+Spring中文文档

    • 更新:使用更新分配将集合值追加到现有集合。append(Object value)+Spring中文文档

    • 更新:使用更新分配将所有集合值追加到现有集合。append(Object…​ values)+Spring中文文档

    • 更新:使用更新分配添加映射条目。entry(Object key, Object value)+Spring中文文档

    • 更新:使用更新分配将所有地图条目添加到地图中。addAll(Map<? extends Object, ? extends Object> map)+Spring中文文档

  • Update remove :使用更新分配从集合中删除值。(String columnName, Object value)-Spring中文文档

  • Update clear :清除集合。(String columnName)Spring中文文档

  • Update increment :使用更新分配进行更新。(String columnName, Number delta)+Spring中文文档

  • Update 递减 :使用更新分配进行更新。(String columnName, Number delta)-Spring中文文档

  • Update set :使用更新分配进行更新。(String columnName, Object value)=Spring中文文档

  • SetBuilder 设置入口点:(String columnName)SetBuilderSpring中文文档

    • 更新:使用更新赋值将给定索引处的集合设置为值。atIndex(int index).to(Object value)=Spring中文文档

    • 更新:将给定键处的映射条目设置为更新分配的值。atKey(String object).to(Object value)=Spring中文文档

以下列表显示了一些更新示例:Spring中文文档

// UPDATE … SET key = 'Spring Data';
Update.update("key", "Spring Data")

// UPDATE … SET key[5] = 'Spring Data';
Update.empty().set("key").atIndex(5).to("Spring Data");

// UPDATE … SET key = key + ['Spring', 'DATA'];
Update.empty().addTo("key").appendAll("Spring", "Data");

请注意,一旦创建,它是不可变的。 调用方法会创建新的不可变(中间)对象。UpdateUpdateSpring中文文档

删除行的方法

可以使用以下重载方法从数据库中删除对象:Spring中文文档

  • boolean delete :删除 选择的对象。(Query query, Class<?> entityClass)QuerySpring中文文档

  • T delete :删除给定对象。(T entity)Spring中文文档

  • T delete :删除应用 的给定对象。(T entity, QueryOptions queryOptions)QueryOptionsSpring中文文档

  • boolean deleteById :使用给定的 ID 删除对象。(Object id, Class<?> entityClass)Spring中文文档

乐观锁定

注解在 Cassandra 上下文中提供类似于 JPA 的语法,并确保更新仅应用于具有匹配版本的行。 Optimistic Locking 利用 Cassandra 的轻量级事务有条件地插入、更新和删除行。 因此,使用条件执行语句。 对于更新和删除,将 version 属性的实际值添加到条件中,这样,如果其他操作在此期间更改了行,则修改不会产生任何影响。 在这种情况下,将抛出一个。 以下示例显示了这些功能:@VersionINSERTIF NOT EXISTSUPDATEOptimisticLockingFailureExceptionSpring中文文档

@Table
class Person {

  @Id String id;
  String firstname;
  String lastname;
  @Version Long version;
}

Person daenerys = template.insert(new Person("Daenerys"));                            (1)

Person tmp = template.findOne(query(where("id").is(daenerys.getId())), Person.class); (2)

daenerys.setLastname("Targaryen");
template.save(daenerys);                                                              (3)

template.save(tmp); // throws OptimisticLockingFailureException                       (4)
1 插入文档。 设置为 。version0
2 加载刚刚插入的文档。 还是.version0
3 使用 更新文档。 将 和 bump 设置为 。version = 0lastnameversion1
4 尝试更新之前加载的文档,该文档仍然具有 . 操作失败,并显示 ,因为电流为 。version = 0OptimisticLockingFailureExceptionversion1
乐观锁定仅支持单实体操作,不支持批处理操作。
插入操作和更新操作之间的区别在于,操作不插入值。INSERTnull
1 插入文档。 设置为 。version0
2 加载刚刚插入的文档。 还是.version0
3 使用 更新文档。 将 和 bump 设置为 。version = 0lastnameversion1
4 尝试更新之前加载的文档,该文档仍然具有 . 操作失败,并显示 ,因为电流为 。version = 0OptimisticLockingFailureExceptionversion1
乐观锁定仅支持单实体操作,不支持批处理操作。