跳到主要内容

预处理语句

ChatGPT-4o-mini 中英对照 Prepared Statements

多次执行的 CQL 语句可以被预处理并存储在 PreparedStatement 对象中,以提高查询性能。驱动程序和 Cassandra 都维护 PreparedStatement 查询及其元数据的映射。你可以通过以下抽象来使用预处理语句:

使用 CqlTemplate

CqlTemplate 类(及其异步和响应式变体)提供了多种方法,这些方法接受静态 CQL、Statement 对象和 PreparedStatementCreator。接受静态 CQL 且没有额外参数的方法通常会直接执行 CQL 语句而不做进一步处理。接受静态 CQL 并结合参数数组的方法(如 execute(String cql, Object…​ args)queryForRows(String cql, Object…​ args))使用预编译语句。在内部,这些方法会创建 PreparedStatementCreatorPreparedStatementBinder 对象来准备语句,并在后续将值绑定到语句上执行。Spring Data Cassandra 通常使用基于索引的参数绑定来处理预编译语句。

自 Cassandra 驱动程序版本 4 起,预编译语句在驱动程序级别进行缓存,从而不再需要在应用程序中跟踪预编译语句。

以下示例展示了如何使用参数化的预处理语句发出查询:

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

在需要更好地控制语句准备和参数绑定的情况下(例如,使用命名绑定参数),您可以通过调用带有 PreparedStatementCreatorPreparedStatementBinder 参数的查询方法,完全控制预处理语句的创建和参数绑定:

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));
java

Spring Data Cassandra 附带了支持该模式的类,位于 cql 包中:

  • SimplePreparedStatementCreator - 工具类,用于创建预处理语句。

  • ArgumentPreparedStatementBinder - 工具类,用于将参数绑定到预处理语句。

使用 CassandraTemplate

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

以下示例展示了生成和接受 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);
java

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

可以在调用接受 Statement 的方法时,通过传入 SimpleStatement 对象来参与预编译语句。模板 API 提取查询字符串和参数(位置参数和命名参数),并使用这些信息来准备、绑定和执行语句。不能使用非 SimpleStatement 对象与预编译语句。

缓存预编译语句

自 Cassandra 驱动程序 4.0 以来,预编译语句由 CqlSession 缓存,因此可以安全地准备相同的字符串两次。以前的版本要求在驱动程序之外缓存预编译语句。有关更多信息,请参见 预编译语句的驱动程序文档