|
对于最新的稳定版本,请使用 Spring Data Cassandra 4.5.2! |
CQL 模板 API
这CqlTemplate类(及其响应式变体ReactiveCqlTemplate) 是核心 CQL 包中的中心类。
它处理资源的创建和释放。
它执行核心 CQL 工作流的基本任务,例如语句创建和执行,并让应用程序代码提供 CQL 并提取结果。
这CqlTemplate类执行 CQL 查询和更新语句,对ResultSet实例和返回参数值的提取。
它还捕获 CQL 异常,并将其转换为org.springframework.dao包。
当您使用CqlTemplate对于您的代码,您只需要实现回调接口,这些接口具有明确定义的合约。
给定一个CqlSession这PreparedStatementCreatorcallback 接口使用提供的 CQL 和任何必要的参数参数创建一个准备好的语句。
这RowCallbackHandler接口从每个行中提取值ResultSet.
这CqlTemplate可以通过使用SessionFactory引用或在 Spring 容器中配置并作为 bean 引用提供给 DAO。CqlTemplate是CassandraTemplate.
此类颁发的所有 CQL 都记录在DEBUG级别,该级别与模板实例的完全限定类名称相对应(通常CqlTemplate,但如果您使用CqlTemplate类)。
您可以通过在 CQL API 实例上配置以下参数来控制获取大小、一致性级别和重试策略默认值:CqlTemplate,AsyncCqlTemplate和ReactiveCqlTemplate.
如果未设置特定查询选项,则默认值适用。
CqlTemplate有不同的执行模型风格。
基本的CqlTemplate使用阻塞执行模型。
您可以使用AsyncCqlTemplate用于异步执行和同步ListenableFutureinstances 或ReactiveCqlTemplate用于反应性执行。 |
示例CqlTemplate类用法
本节提供了一些示例CqlTemplate在行动的课堂。
这些示例并不是CqlTemplate.
有关此信息,请参阅 Javadoc。
查询 (SELECT)CqlTemplate
以下查询获取表中的行数:
-
Imperative
-
Reactive
int rowCount = cqlTemplate.queryForObject("SELECT COUNT(*) FROM t_actor", Integer.class);
Mono<Integer> rowCount = reactiveCqlTemplate.queryForObject("SELECT COUNT(*) FROM t_actor", Integer.class);
以下查询使用绑定变量:
-
Imperative
-
Reactive
int countOfActorsNamedJoe = cqlTemplate.queryForObject(
"SELECT COUNT(*) FROM t_actor WHERE first_name = ?", Integer.class, "Joe");
Mono<Integer> countOfActorsNamedJoe = reactiveCqlTemplate.queryForObject(
"SELECT COUNT(*) FROM t_actor WHERE first_name = ?", Integer.class, "Joe");
以下示例查询String:
-
Imperative
-
Reactive
String lastName = cqlTemplate.queryForObject(
"SELECT last_name FROM t_actor WHERE id = ?",
String.class, 1212L);
Mono<String> lastName = reactiveCqlTemplate.queryForObject(
"SELECT last_name FROM t_actor WHERE id = ?",
String.class, 1212L);
以下示例查询并填充单个域对象:
-
Imperative
-
Reactive
Actor actor = cqlTemplate.queryForObject("SELECT first_name, last_name FROM t_actor WHERE id = ?",
new RowMapper<Actor>() {
public Actor mapRow(Row row, int rowNum) {
Actor actor = new Actor();
actor.setFirstName(row.getString("first_name"));
actor.setLastName(row.getString("last_name"));
return actor;
}
}, 1212L);
Mono<Actor> actor = reactiveCqlTemplate.queryForObject(
"SELECT first_name, last_name FROM t_actor WHERE id = ?",
new RowMapper<Actor>() {
public Actor mapRow(Row row, int rowNum) {
Actor actor = new Actor();
actor.setFirstName(row.getString("first_name"));
actor.setLastName(row.getString("last_name"));
return actor;
}},
1212L);
以下示例查询并填充多个域对象:
-
Imperative
-
Reactive
List<Actor> actors = cqlTemplate.query(
"SELECT first_name, last_name FROM t_actor",
new RowMapper<Actor>() {
public Actor mapRow(Row row, int rowNum) {
Actor actor = new Actor();
actor.setFirstName(row.getString("first_name"));
actor.setLastName(row.getString("last_name"));
return actor;
}
});
Flux<Actor> actors = reactiveCqlTemplate.query(
"SELECT first_name, last_name FROM t_actor",
new RowMapper<Actor>() {
public Actor mapRow(Row row, int rowNum) {
Actor actor = new Actor();
actor.setFirstName(row.getString("first_name"));
actor.setLastName(row.getString("last_name"));
return actor;
}
});
如果最后两个代码片段实际上存在于同一个应用程序中,那么删除两个代码片段中存在的重复是有意义的RowMapper匿名内部类并将它们提取到单个类中(通常是static嵌套类),然后可以被 DAO 方法引用。
例如,最好按如下方式编写最后一个代码片段:
-
Imperative
-
Reactive
List<Actor> findAllActors() {
return cqlTemplate.query("SELECT first_name, last_name FROM t_actor", ActorMapper.INSTANCE);
}
enum ActorMapper implements RowMapper<Actor> {
INSTANCE;
public Actor mapRow(Row row, int rowNum) {
Actor actor = new Actor();
actor.setFirstName(row.getString("first_name"));
actor.setLastName(row.getString("last_name"));
return actor;
}
}
Flux<Actor> findAllActors() {
return reactiveCqlTemplate.query("SELECT first_name, last_name FROM t_actor", ActorMapper.INSTANCE);
}
enum ActorMapper implements RowMapper<Actor> {
INSTANCE;
public Actor mapRow(Row row, int rowNum) {
Actor actor = new Actor();
actor.setFirstName(row.getString("first_name"));
actor.setLastName(row.getString("last_name"));
return actor;
}
}
INSERT,UPDATE和DELETE跟CqlTemplate
您可以使用execute(…)执行方法INSERT,UPDATE和DELETE操作。
参数值通常作为变量参数提供,或者作为对象数组提供。
以下示例演示如何执行INSERT作CqlTemplate:
-
Imperative
-
Reactive
cqlTemplate.execute(
"INSERT INTO t_actor (first_name, last_name) VALUES (?, ?)",
"Leonor", "Watling");
Mono<Boolean> applied = reactiveCqlTemplate.execute(
"INSERT INTO t_actor (first_name, last_name) VALUES (?, ?)",
"Leonor", "Watling");
以下示例演示如何执行UPDATE作CqlTemplate:
-
Imperative
-
Reactive
cqlTemplate.execute(
"UPDATE t_actor SET last_name = ? WHERE id = ?",
"Banjo", 5276L);
Mono<Boolean> applied = reactiveCqlTemplate.execute(
"UPDATE t_actor SET last_name = ? WHERE id = ?",
"Banjo", 5276L);
以下示例演示如何执行DELETE作CqlTemplate:
-
Imperative
-
Reactive
cqlTemplate.execute(
"DELETE FROM t_actor WHERE id = ?",
5276L);
Mono<Boolean> applied = reactiveCqlTemplate.execute(
"DELETE FROM actor WHERE id = ?",
actorId);
其他CqlTemplate操作
您可以使用execute(..)方法来执行任何任意 CQL。
因此,该方法通常用于 DDL 语句。
它严重重载了采用回调接口、绑定变量数组等的变体。
以下示例演示如何使用不同的 API 对象创建和删除表,这些对象都传递给execute()方法:
cqlTemplate.execute("CREATE TABLE test_table (id uuid primary key, event text)");
DropTableSpecification dropper = DropTableSpecification.dropTable("test_table");
String cql = DropTableCqlGenerator.toCql(dropper);
cqlTemplate.execute(cql);
控制 Cassandra 连接
应用程序通过使用CqlSession对象。
卡桑德拉CqlSession跟踪与各个节点的多个连接,并被设计为线程安全的长期对象。
通常,您可以使用单个CqlSession适用于整个应用程序。
Spring 获得 CassandraCqlSession通过SessionFactory.SessionFactory是 Spring Data for Apache Cassandra 的一部分,是一个通用的连接工厂。
它允许容器或框架从应用程序代码中隐藏连接处理和路由问题。
以下示例演示如何配置默认SessionFactory:
-
Imperative
-
Reactive
CqlSession session = … // get a Cassandra Session
CqlTemplate template = new CqlTemplate();
template.setSessionFactory(new DefaultSessionFactory(session));
CqlSession session = … // get a Cassandra Session
ReactiveCqlTemplate template = new ReactiveCqlTemplate(new DefaultBridgedReactiveSession(session));
CqlTemplate和其他模板 API 实现会获得CqlSession对于每个作。由于会话的长期性质,会话在调用所需作后不会关闭。正确资源处置的责任在于使用会话的容器或框架。
你可以找到各种SessionFactory中的实现org.springframework.data.cassandra.core.cql.session包。
异常转换
Spring Framework 为各种数据库和映射技术提供了异常转换。这传统上是针对 JDBC 和 JPA 的。Spring Data for Apache Cassandra 通过提供org.springframework.dao.support.PersistenceExceptionTranslator接口。
映射到 Spring 一致的数据访问异常层次结构背后的动机是让您编写可移植的描述性异常处理代码,而无需诉诸于针对和处理特定的 Cassandra 异常进行编码和处理。Spring 的所有数据访问异常都继承自DataAccessException类,因此您可以确保可以在单个 try-catch 块中捕获所有与数据库相关的异常。
ReactiveCqlTemplate和ReactiveCassandraTemplate尽早传播异常。在处理反应序列期间发生的异常将作为错误信号发出。