Persisting Entities
这个类实现了 CassandraOperations 和 ReactiveCassandraOperations 接口,方法以 Cassandra 中可用方法的名称命名,以便对于已经熟悉 Cassandra 的开发人员来说,该 API 是比较熟悉的。例如,你可以找到诸如 select、insert、delete 和 update 等方法。设计目标是尽可能简化在使用基本 Cassandra 驱动程序和使用 [Reactive]CassandraOperations 之间的转换。这两个 API 之间的一个主要区别是,可以向 CassandraOperations 传递域对象,而不是 CQL 和查询对象。
位于 org.springframework.data.cassandra
包中的 CassandraTemplate
类(及其反应式变体 ReactiveCassandraTemplate
)是 Spring 的 Cassandra 支持中的中心类,并提供丰富的功能集以与数据库交互。该模板提供便利操作以创建、更新、删除和查询 Cassandra,并在你的域对象和 Cassandra 表格中的行之间提供映射。
The CassandraTemplate
class (and its reactive variant ReactiveCassandraTemplate
), located in the org.springframework.data.cassandra
package, is the central class in Spring’s Cassandra support and provides a rich feature set to interact with the database.
The template offers convenience operations to create, update, delete, and query Cassandra, and provides a mapping between your domain objects and rows in Cassandra tables.
进行配置后,模板实例是线程安全的,并且可以在多个实例之间重用。 |
Once configured, a template instance is thread-safe and can be reused across multiple instances. |
行在 Cassandra 和应用程序域类之间的映射通过委托给 CassandraConverter`接口的实现而完成。Spring 提供一个默认实现,即 `MappingCassandraConverter
,但是您也可以编写自己的自定义转换器。有关更详细的信息,请参阅 Cassandra conversion 章节。
The mapping between rows in Cassandra and application domain classes is done by delegating to an implementation of the CassandraConverter
interface.
Spring provides a default implementation, MappingCassandraConverter
, but you can also write your own custom converter.
See the section on
Cassandra conversion for more detailed information.
CassandraTemplate
类实现 CassandraOperations
接口,其反应式变体 ReactiveCassandraTemplate
实现 ReactiveCassandraOperations
。[Reactive]CassandraOperations
上的方法尽可能以 Cassandra 中可用的方法命名,以使已经熟悉 Cassandra 的开发者熟悉 API。
The CassandraTemplate
class implements the CassandraOperations
interface and its reactive variant ReactiveCassandraTemplate
implements ReactiveCassandraOperations
.
In as much as possible, the methods on [Reactive]CassandraOperations
are named after methods available in Cassandra to make the API familiar to developers who are already familiar with Cassandra.
例如,您可以找到诸如 select
、insert
、delete
和 update
的方法。设计目标是在使用基本 Cassandra 驱动程序和 [Reactive]CassandraOperations
之间尽可能轻松地进行切换。两个 API 之间的一个主要区别是,CassandraOperations
可以传递域对象,而不是 CQL 和查询对象。
For example, you can find methods such as select
, insert
, delete
, and update
.
The design goal was to make it as easy as possible to transition between the use of the base Cassandra driver and [Reactive]CassandraOperations
.
A major difference between the two APIs is that CassandraOperations
can be passed domain objects instead of CQL and query objects.
引用 |
The preferred way to reference operations on a |
[Reactive]CassandraTemplate
使用的默认转换器实现为 MappingCassandraConverter
。虽然 MappingCassandraConverter
可以使用附加元数据来指定对象到行的映射,但它还可以转换不包含任何附加元数据的对象,方法是使用用于映射字段和表名的某些约定。这些约定以及映射注解的使用在 “Mapping” chapter 中进行了说明。
The default converter implementation used by [Reactive]CassandraTemplate
is MappingCassandraConverter
.
While MappingCassandraConverter
can use additional metadata to specify the mapping of objects to rows, it can also convert objects that contain no additional metadata by using some conventions for the mapping of fields and table names.
These conventions, as well as the use of mapping annotations, are explained in the “Mapping” chapter.
`[Reactive]CassandraTemplate`的另一个核心特性是将 Cassandra Java 驱动程序中抛出的异常转换为 Spring 的可移植数据访问异常层次结构。有关详细信息,请参见exception translation部分。
Another central feature of [Reactive]CassandraTemplate
is exception translation of exceptions thrown in the Cassandra Java driver into Spring’s portable Data Access Exception hierarchy.
See the section on
exception translation for more information.
模板 API 具有不同的执行模型风格。基本的 |
The Template API has different execution model flavors.
The basic |
Instantiating CassandraTemplate
虽然我们在前面展示了一个直接示例化 CassandraTemplate
的示例,但 CassandraTemplate
总是应当配置为 Spring bean。但是,由于我们假定正在构建一个 Spring 模块,因此我们假设存在 Spring 容器。
CassandraTemplate
should always be configured as a Spring bean, although we show an example earlier where you can instantiate it directly.
However, because we are assuming the context of making a Spring module, we assume the presence of the Spring container.
有两种方法可以获取一个 CassandraTemplate
,具体取决于你如何加载 Spring ApplicationContext
:
There are two ways to get a CassandraTemplate
, depending on how you load you Spring ApplicationContext
:
您可以根据项目将 [Reactive]CassandraOperations
注入到项目中,如以下示例所示:
You can autowire a [Reactive]CassandraOperations
into your project, as the following example shows:
-
Imperative
-
Reactive
@Autowired
private CassandraOperations cassandraOperations;
@Autowired
private ReactiveCassandraOperations reactiveCassandraOperations;
与所有 Spring 注入一样,这假定 ApplicationContext
中只有类型为 [Reactive]CassandraOperations
的一个 Bean。如果有多个 [Reactive]CassandraTemplate
Bean(当您在同一项目中使用多个键空间时会出现这种情况),那么可以使用 @Qualifier
注解来指定您想要注入的 Bean。
As with all Spring autowiring, this assumes there is only one bean of type [Reactive]CassandraOperations
in the ApplicationContext
.
If you have multiple [Reactive]CassandraTemplate
beans (which is the case if you work with multiple keyspaces in the same project), then you can use the @Qualifier
annotation to designate the bean you want to autowire.
-
Imperative
-
Reactive
@Autowired
@Qualifier("keyspaceOneTemplateBeanId")
private CassandraOperations cassandraOperations;
@Autowired
@Qualifier("keyspaceOneTemplateBeanId")
private ReactiveCassandraOperations reactiveCassandraOperations;
ApplicationContext
您还可以从 ApplicationContext
中查找 [Reactive]CassandraTemplate
Bean,如以下示例所示:
You can also look up the [Reactive]CassandraTemplate
bean from the ApplicationContext
, as shown in the following example:
-
Imperative
-
Reactive
CassandraOperations cassandraOperations = applicationContext.getBean("cassandraTemplate", CassandraOperations.class);
ReactiveCassandraOperations cassandraOperations = applicationContext.getBean("ReactiveCassandraOperations", ReactiveCassandraOperations.class);
Querying Rows
你可以通过使用 Query
和 Criteria
类来表示你的查询,这些类具有反映本地 Cassandra 谓词运算符名称的方法名称,例如 lt
、lte
、is
等。
You can express your queries by using the Query
and Criteria
classes, which have method names that reflect the native Cassandra predicate operator names, such as lt
, lte
, is
, and others.
Query
和 Criteria
类遵循流利 API 样式,这样你可以在具有易于理解的代码的情况下,轻松地将多个方法条件和查询链接到一起。在创建 Query
和 Criteria
实例时会在 Java 中使用静态导入以提高可读性。
The Query
and Criteria
classes follow a fluent API style so that you can easily chain together multiple method criteria and queries while having easy-to-understand code.
Static imports are used in Java when creating Query
and Criteria
instances to improve readability.
Querying Rows in a Table
在前面的几个章节中,我们看到了如何使用 [Reactive]CassandraTemplate
上的 selectOneById
方法来检索单个对象。这样做可返回单个域对象。我们还可以查询一组行,并将它们作为域对象列表返回。假设我们有一些 Person
对象,其中名称和年龄值存储在表中的行中,并且每个人都有一个帐户余额,那么我们现在可以通过使用以下代码来运行查询:
In earlier sections, we saw how to retrieve a single object by using the selectOneById
method on [Reactive]CassandraTemplate
.
Doing so returns a single domain object.
We can also query for a collection of rows to be returned as a list of domain objects.
Assuming we have a number of Person
objects with name and age values stored as rows in a table and that each person has an account balance, we can now run a query by using the following code:
[Reactive]CassandraTemplate
-
Imperative
-
Reactive
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);
select
、selectOne
和 stream
方法将 Query
对象作为参数。此对象定义用于执行该查询的条件和选项。该条件通过使用静态工厂方法 where
来指定,后者实例化一个新的 Criteria
对象。我们建议对 org.springframework.data.cassandra.core.query.Criteria.where
和 Query.query
进行静态导入,以使查询更具可读性。
The select
, selectOne
, and stream
methods take a Query
object as a parameter.
This object defines the criteria and options used to perform the query.
The criteria is specified by using a Criteria
object that has a static factory method named where
that instantiates a new Criteria
object.
We recommend using a static import for org.springframework.data.cassandra.core.query.Criteria.where
and Query.query
, to make the query more readable.
此查询应返回满足指定条件的一列 Person
对象,Criteria
类具有以下方法,这些方法与 Apache Cassandra 中提供的运算符相对应:
This query should return a list of Person
objects that meet the specified criteria.
The Criteria
class has the following methods that correspond to the operators provided in Apache Cassandra:
Methods for the Criteria class
-
CriteriaDefinition
gt(Object value)
: Creates a criterion by using the>
operator. -
CriteriaDefinition
gte(Object value)
: Creates a criterion by using the>=
operator. -
CriteriaDefinition
in(Object… values)
: Creates a criterion by using theIN
operator for a varargs argument. -
CriteriaDefinition
in(Collection<?> collection)
: Creates a criterion by using theIN
operator using a collection. -
CriteriaDefinition
is(Object value)
: Creates a criterion by using field matching (column = value
). -
CriteriaDefinition
lt(Object value)
: Creates a criterion by using the<
operator. -
CriteriaDefinition
lte(Object value)
: Creates a criterion by using the⇐
operator. -
CriteriaDefinition
like(Object value)
: Creates a criterion by using theLIKE
operator. -
CriteriaDefinition
contains(Object value)
: Creates a criterion by using theCONTAINS
operator. -
CriteriaDefinition
containsKey(Object key)
: Creates a criterion by using theCONTAINS KEY
operator.
创建后,Criteria
します。
Criteria
is immutable once created.
Methods for the Query class
Query
类有一些附加方法,您可以使用它们为查询提供选项:
The Query
class has some additional methods that you can use to provide options for the query:
-
Query
by(CriteriaDefinition… criteria)
: Used to create aQuery
object. -
Query
and(CriteriaDefinition criteria)
: Used to add additional criteria to the query. -
Query
columns(Columns columns)
: Used to define columns to be included in the query results. -
Query
limit(Limit limit)
: Used to limit the size of the returned results to the provided limit (usedSELECT
limiting). -
Query
limit(long limit)
: Used to limit the size of the returned results to the provided limit (usedSELECT
limiting). -
Query
pageRequest(Pageable pageRequest)
: Used to associateSort
,PagingState
, andfetchSize
with the query (used for paging). -
Query
pagingState(ByteBuffer pagingState)
: Used to associate aByteBuffer
with the query (used for paging). -
Query
queryOptions(QueryOptions queryOptions)
: Used to associateQueryOptions
with the query. -
Query
sort(Sort sort)
: Used to provide a sort definition for the results. -
Query
withAllowFiltering()
: Used to renderALLOW FILTERING
queries.
创建后,Query
します。调用方法会创建新的不可变(中间)Query
对象。
Query
is immutable once created.
Invoking methods creates new immutable (intermediate) Query
objects.
Methods for Querying for Rows
Query
类具有以下返回行的各项方法:
The Query
class has the following methods that return rows:
-
List<T>
select(Query query, Class<T> entityClass)
: Query for a list of objects of typeT
from the table. -
T
selectOne(Query query, Class<T> entityClass)
: Query for a single object of typeT
from the table. -
Slice<T>
slice(Query query, Class<T> entityClass)
: Starts or continues paging by querying for aSlice
of objects of typeT
from the table. -
Stream<T>
stream(Query query, Class<T> entityClass)
: Query for a stream of objects of typeT
from the table. -
List<T>
select(String cql, Class<T> entityClass)
: Ad-hoc query for a list of objects of typeT
from the table by providing a CQL statement. -
T
selectOne(String cql, Class<T> entityClass)
: Ad-hoc query for a single object of typeT
from the table by providing a CQL statement. -
Stream<T>
stream(String cql, Class<T> entityClass)
: Ad-hoc query for a stream of objects of typeT
from the table by providing a CQL statement.
查询方法必须指定要返回的目标类型 T
。
The query methods must specify the target type T
that is returned.
Fluent Template API
[Reactive]CassandraOperations
接口在与 Apache Cassandra 进行更低级别的交互时是核心组件之一。它提供了多种方法。您可以找到每个方法的多个重载。它们大多数涵盖了 API 的可选(可为 null)部分。
The [Reactive]CassandraOperations
interface is one of the central components when it comes to more low-level interaction with Apache Cassandra.
It offers a wide range of methods.
You can find multiple overloads for every method.
Most of them cover optional (nullable) parts of the API.
FluentCassandraOperations
及其反应式变体 ReactiveFluentCassandraOperations
为 [Reactive]CassandraOperations
的常用方法提供一个更窄的接口,它提供了一个更易读的、流畅的 API。入口点 (query(…)
、insert(…)
、update(…)
和 delete(…)
) 遵循一个基于要执行的操作的自然命名方案。从入口点开始,该 API 被设计为仅提供上下文相关的帮助开发者通向调用实际 [Reactive]CassandraOperations
的终止方法的方法。以下示例展示了流畅 API:
FluentCassandraOperations
and its reactive variant ReactiveFluentCassandraOperations
provide a more narrow interface for common methods of [Reactive]CassandraOperations
providing a more readable, fluent API.
The entry points (query(…)
, insert(…)
, update(…)
, and delete(…)
) follow a natural naming scheme based on the operation to execute.
Moving on from the entry point, the API is designed to offer only context-dependent methods that guide the developer towards a terminating method that invokes the actual [Reactive]CassandraOperations
.
The following example shows the fluent API:
- Imperative
-
List<SWCharacter> all = ops.query(SWCharacter.class) .inTable("star_wars") 1 .all();
1 | Skip this step if SWCharacter defines the table name with @Table or if using the class name as the table name is not a problem
|
2 | Skip this step if SWCharacter defines the table name with @Table or if using the class name as the table name is not a problem |
如果 Cassandra 中的表存储不同类型的实体,例如 SWCharacters
表中的 Jedi
,则可以使用不同的类型映射查询结果。您可以使用 as(Class<?> targetType)
将结果映射到不同的目标类型,而 query(Class<?> entityType)
仍应用于查询和表名。以下示例使用了 query
和 as
方法:
If a table in Cassandra holds entities of different types, such as a Jedi
within a Table of SWCharacters
, you can use different types to map the query result.
You can use as(Class<?> targetType)
to map results to a different target type, while query(Class<?> entityType)
still applies to the query and table name.
The following example uses the query
and as
methods:
- Imperative
-
List<Jedi> all = ops.query(SWCharacter.class) 1 .as(Jedi.class) 2 .matching(query(where("jedi").is(true))) .all();
1 | The query fields are mapped against the SWCharacter type. |
2 | Resulting rows are mapped into Jedi .
|
3 | The query fields are mapped against the SWCharacter type. |
4 | Resulting rows are mapped into Jedi . |
您可以仅通过 |
You can directly apply Projections to resulting documents by providing only the |
终止方法(first()
、one()
、all()
和 stream()
)处理在检索单个实体和检索多个实体(作为 List
或 Stream
)之间切换之类的操作。
The terminating methods (first()
, one()
, all()
, and stream()
) handle switching between retrieving a single entity and retrieving multiple entities as List
or Stream
and similar operations.
新的利于理解的模板 API 方法(即 query(..)
、insert(..)
、update(..)
和 delete(..)
)有效地使用线程安全支持对象组合 CQL 语句。但是,它带来了额外的新生代 JVM 堆开销,因为设计基于各种 CQL 语句组件的最终字段和在变更中构造。当可能插入或删除大量对象时(例如在循环内),您应小心。
The new fluent template API methods (that is, query(..)
, insert(..)
, update(..)
, and delete(..)
) use effectively thread-safe supporting objects to compose the CQL statement.
However, it comes at the added cost of additional young-gen JVM heap overhead, since the design is based on final fields for the various CQL statement components and construction on mutation.
You should be careful when possibly inserting or deleting a large number of objects (such as inside of a loop, for instance).
Saving, Updating, and Removing Rows
[Reactive]CassandraTemplate
为您提供了保存、更新和删除您的域对象,以及将这些对象映射到 Cassandra 中管理的表的一种简单方法。
[Reactive]CassandraTemplate
provides a simple way for you to save, update, and delete your domain objects and map those objects to tables managed in Cassandra.
Type Mapping
Spring Data for Apache Cassandra 依赖于 DataStax Java 驱动程序的`CodecRegistry`以确保类型支持。随着类型的添加或更改,Spring Data for Apache Cassandra 模块继续运行,而不需要进行更改。有关当前类型映射矩阵,请参见 CQL data types和 “Data Mapping and Type Conversion”。
Spring Data for Apache Cassandra relies on the DataStax Java driver’s CodecRegistry
to ensure type support.
As types are added or changed, the Spring Data for Apache Cassandra module continues to function without requiring changes.
See CQL data types
and “Data Mapping and Type Conversion” for the current type mapping matrix.
Methods for Inserting and Updating rows
[Reactive]CassandraTemplate
有几个使您能够保存和插入您的对象的便捷方法。为了对转换过程进行更细粒度的控制,您可以向 MappingCassandraConverter
注册 Spring Converter
实例(例如,Converter<Row, Person>
)。
[Reactive]CassandraTemplate
has several convenient methods for saving and inserting your objects.
To have more fine-grained control over the conversion process, you can register Spring Converter
instances with the MappingCassandraConverter
(for example, Converter<Row, Person>
).
插入操作和更新操作之间的区别在于, |
The difference between insert and update operations is that |
使用 INSERT
操作的简单情况是保存 POJO。在这种情况下,表名由简单类名决定(而不是完全限定的类名)。可以通过使用映射元数据来覆盖用于存储对象的表。
The simple case of using the INSERT
operation is to save a POJO.
In this case, the table name is determined by the simple class name (not the fully qualified class name).
The table to store the object can be overridden by using mapping metadata.
插入或更新时,必须设置 id
属性。Apache Cassandra 无法生成 ID。
When inserting or updating, the id
property must be set.
Apache Cassandra has no means to generate an ID.
以下示例使用了 save 操作并检索其内容:
The following example uses the save operation and retrieves its contents:
[Reactive]CassandraTemplate
-
Imperative
-
Reactive
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);
您可以使用以下操作进行插入和保存:
You can use the following operations to insert and save:
-
void
insert(Object objectToSave)
: Inserts the object in an Apache Cassandra table. -
WriteResult
insert(Object objectToSave, InsertOptions options)
: Inserts the object in an Apache Cassandra table and appliesInsertOptions
.
您可以使用以下更新操作:
You can use the following update operations:
-
void
update(Object objectToSave)
: Updates the object in an Apache Cassandra table. -
WriteResult
update(Object objectToSave, UpdateOptions options)
: Updates the object in an Apache Cassandra table and appliesUpdateOptions
.
您还可以使用老式方法编写自己的 CQL 语句,如下面的示例所示:
You can also use the old fashioned way and write your own CQL statements, as the following example shows:
-
Imperative
-
Reactive
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);
您还可以使用 InsertOptions
和 UpdateOptions
配置其他选项,例如 TTL、一致性级别和轻量级事务。
You can also configure additional options such as TTL, consistency level, and lightweight transactions when using InsertOptions
and UpdateOptions
.
Which Table Are My Rows Inserted into?
您可以通过两种方式管理用于操作表的表名。默认的表名是简单类名,将其更改为以小写字母开头。因此,com.example.Person
类的实例将存储在 person
表中。第二种方式是指定 @Table
注解中的表名。
You can manage the table name that is used for operating on the tables in two ways.
The default table name is the simple class name changed to start with a lower-case letter.
So, an instance of the com.example.Person
class would be stored in the person
table.
The second way is to specify a table name in the @Table
annotation.
Inserting, Updating, and Deleting Individual Objects in a Batch
Cassandra 协议支持通过批量使用一次操作插入集合行。
The Cassandra protocol supports inserting a collection of rows in one operation by using a batch.
[Reactive]CassandraTemplate
接口中的以下方法支持此功能:
The following methods in the [Reactive]CassandraTemplate
interface support this functionality:
-
batchOps
: Creates a new[Reactive]CassandraBatchOperations
to populate the batch.
[Reactive]CassandraBatchOperations
-
insert
: Takes a single object, an array (var-args), or anIterable
of objects to insert. -
update
: Takes a single object, an array (var-args), or anIterable
of objects to update. -
delete
: Takes a single object, an array (var-args), or anIterable
of objects to delete. -
withTimestamp
: Applies a TTL to the batch. -
execute
: Executes the batch.
Updating Rows in a Table
对于更新,您可以选择更新多行。
For updates, you can select to update a number of rows.
以下示例显示了通过将一次性 50.00 美元的奖励加到余额中来更新单个帐户对象,分配 +
:
The following example shows updating a single account object by adding a one-time $50.00 bonus to the balance with the +
assignment:
[Reactive]CasandraTemplate
-
Imperative
-
Reactive
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);
除了前面讨论的 Query
外,我们还使用 Update
对象提供更新定义。Update
类具有与 Apache Cassandra 可用更新分配匹配的方法。
In addition to the Query
discussed earlier, we provide the update definition by using an Update
object.
The Update
class has methods that match the update assignments available for Apache Cassandra.
大多数方法返回 Update
对象以提供一种流畅的 API 用于代码样式目的。
Most methods return the Update
object to provide a fluent API for code styling purposes.
Methods for Executing Updates for Rows
更新方法可以更新行,如下所示:
The update method can update rows, as follows:
-
boolean
update(Query query, Update update, Class<?> entityClass)
: Updates a selection of objects in the Apache Cassandra table.
Methods for the Update class
Update
类可以与少量“语法糖”一起使用,因为它的方法是为了链接在一起的。此外,您可以使用静态方法 public static Update update(String key, Object value)
和静态导入来启动创建新的 Update
实例。
The Update
class can be used with a little 'syntax sugar', as its methods are meant to be chained together.
Also, you can kick-start the creation of a new Update
instance with the static method public static Update update(String key, Object value)
and by using static imports.
Update
类具有以下方法:
The Update
class has the following methods:
-
AddToBuilder
addTo(String columnName)
AddToBuilder
entry-point:-
Update
prepend(Object value)
: Prepends a collection value to the existing collection by using the+
update assignment. -
Update
prependAll(Object… values)
: Prepends all collection values to the existing collection by using the+
update assignment. -
Update
append(Object value)
: Appends a collection value to the existing collection by using the+
update assignment. -
Update
append(Object… values)
: Appends all collection values to the existing collection by using the+
update assignment. -
Update
entry(Object key, Object value)
: Adds a map entry by using the+
update assignment. -
Update
addAll(Map<? extends Object, ? extends Object> map)
: Adds all map entries to the map by using the+
update assignment.
-
-
Update
remove(String columnName, Object value)
: Removes the value from the collection by using the-
update assignment. -
Update
clear(String columnName)
: Clears the collection. -
Update
increment(String columnName, Number delta)
: Updates by using the+
update assignment. -
Update
decrement(String columnName, Number delta)
: Updates by using the-
update assignment. -
Update
set(String columnName, Object value)
: Updates by using the=
update assignment. -
SetBuilder
set(String columnName)
SetBuilder
entry-point:-
Update
atIndex(int index).to(Object value)
: Sets a collection at the given index to a value using the=
update assignment. -
Update
atKey(String object).to(Object value)
: Sets a map entry at the given key to a value the=
update assignment.
-
以下清单显示一些更新示例:
The following listing shows a few update examples:
// 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");
请注意,Update
在创建后不可变。调用方法会创建新的不可变(中间)Update
对象。
Note that Update
is immutable once created.
Invoking methods creates new immutable (intermediate) Update
objects.
Methods for Removing Rows
您可以使用以下重载方法从数据库中删除对象:
You can use the following overloaded methods to remove an object from the database:
-
boolean
delete(Query query, Class<?> entityClass)
: Deletes the objects selected byQuery
. -
T
delete(T entity)
: Deletes the given object. -
T
delete(T entity, QueryOptions queryOptions)
: Deletes the given object applyingQueryOptions
. -
boolean
deleteById(Object id, Class<?> entityClass)
: Deletes the object using the given Id.
Optimistic Locking
@Version
注释提供了类似于 Cassandra 上下文中的 JPA 的语法,并确保更新仅应用于具有匹配版本的行。乐观锁利用 Cassandra 的轻量级事务来有条件地插入、更新和删除行。因此,INSERT
语句以 IF NOT EXISTS
条件执行。对于更新和删除,将实际版本属性值添加到 UPDATE
条件中,以便如果另一个操作同时更改行,则修改不会产生任何影响。这种情况会抛出 OptimisticLockingFailureException
。以下示例显示了这些功能:
The @Version
annotation provides syntax similar to that of JPA in the context of Cassandra and makes sure updates are only applied to rows with a matching version.
Optimistic Locking leverages Cassandra’s lightweight transactions to conditionally insert, update and delete rows.
Therefore, INSERT
statements are executed with the IF NOT EXISTS
condition.
For updates and deletes, the actual value of the version property is added to the UPDATE
condition in such a way that the modification does not have any effect if another operation altered the row in the meantime.
In that case, an OptimisticLockingFailureException
is thrown.
The following example shows these features:
@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 | Intially insert document. version is set to 0 . |
2 | Load the just inserted document. version is still 0 . |
3 | Update the document with version = 0 .
Set the lastname and bump version to 1 . |
4 | Try to update the previously loaded document that still has version = 0 .
The operation fails with an OptimisticLockingFailureException , as the current version is 1 . |
乐观锁仅受支持于单实体操作,而不受支持于批处理操作。 |
Optimistic Locking is only supported with single-entity operations and not for batch operations. |