跳到主要内容
版本:5.1.1

预编译语句

Doubao 中英对照 Prepared Statements

多次执行的 CQL 语句可以预编译并存储在 PreparedStatement 对象中,以提升查询性能。驱动和 Cassandra 都会维护 PreparedStatement 查询与其元数据的映射。您可以通过以下抽象使用预编译语句:

使用 CqlTemplate​

CqlTemplate 类(及其异步和响应式变体)提供了多种方法,可接受静态 CQL、Statement 对象和 PreparedStatementCreator。接受静态 CQL 且不带额外参数的方法通常会按原样运行 CQL 语句,不做进一步处理。接受静态 CQL 并配合参数数组的方法(如 execute(String cql, Object… args) 和 queryForRows(String cql, Object… args))会使用预编译语句。在内部,这些方法会创建 PreparedStatementCreator 和 PreparedStatementBinder 对象来预编译语句,之后再把值绑定到语句上以运行它。Spring Data Cassandra 通常对预编译语句使用基于索引的参数绑定。

自 Cassandra Driver 4 起,预编译语句在驱动层缓存,因此无需在应用中跟踪预编译语句。

以下示例展示了如何使用带参数的预编译语句发起查询:

String lastName = cqlTemplate.queryForObject(
"SELECT last_name FROM t_actor WHERE id = ?",
String.class, 1212L);

如果您需要对语句预编译和参数绑定进行更多控制(例如使用命名绑定参数),可以通过调用带 PreparedStatementCreator 和 PreparedStatementBinder 参数的查询方法,完全掌控预编译语句的创建和参数绑定:

List<String> lastNames = cqlTemplate.query(
session -> session.prepare("SELECT last_name FROM t_actor WHERE id = ?"),
ps -> ps.bind(1212L),
(row, rowNum) -> row.getString(0));

Spring Data Cassandra 在 cql 包中自带了支持该模式的类:

  • SimplePreparedStatementCreator——用于创建预编译语句的工具类。

  • ArgumentPreparedStatementBinder——用于将参数绑定到预编译语句的工具类。

使用 CassandraTemplate​

CassandraTemplate 类构建在 CqlTemplate 之上,以提供更高层次的抽象。可以直接在 CassandraTemplate(及其异步和响应式变体)上通过调用 setUsePreparedStatements(false) 或 setUsePreparedStatements(true) 来控制是否使用预编译语句。请注意,CassandraTemplate 默认启用预编译语句。

以下示例展示了生成 CQL 的方法和接受 CQL 的方法的用法:

template.setUsePreparedStatements(true);

Actor actorByQuery = template.selectOne(query(where("id").is(42)), Actor.class);

Actor actorByStatement = template.selectOne(
SimpleStatement.newInstance("SELECT id, name FROM actor WHERE id = ?", 42),
Actor.class);

调用与实体绑定的方法(如 select(Query, Class<T>) 或 update(Query, Update, Class<T>))会自行构建 CQL 语句来执行预期操作。一些 CassandraTemplate 方法(如 select(Statement<?>, Class<T>))也接受 CQL Statement 对象作为其 API 的一部分。

调用接受 Statement 的方法时传入 SimpleStatement 对象,即可参与预编译语句。模板 API 会提取查询字符串和参数(位置参数和命名参数),并用它们来预编译、绑定和运行语句。非 SimpleStatement 对象不能用于预编译语句。

预编译语句缓存​

自 Cassandra driver 4.0 起,预编译语句由 CqlSession 缓存缓存,因此可以放心地重复预编译同一个字符串。早期版本需要在驱动之外缓存预编译语句。另请参阅驱动文档中关于预编译语句的更多参考。