|
|
|
|
@@ -520,7 +520,7 @@ The `CqlTemplate` class executes CQL queries and update statements, performs ite
|
|
|
|
|
It also catches CQL exceptions and translates them to the generic, more informative, exception hierarchy defined in the `org.springframework.dao` package.
|
|
|
|
|
|
|
|
|
|
When you use the `CqlTemplate` for your code, you need only implement callback interfaces, which have a clearly defined contract.
|
|
|
|
|
Given a `Connection`, the `PreparedStatementCreator` callback interface creates a prepared statement with the provided CQL and any necessary parameter arguments.
|
|
|
|
|
Given a `Connection`, the `PreparedStatementCreator` callback interface creates a <<cassandra.template.prepared-statements.cql,prepared statement>> with the provided CQL and any necessary parameter arguments.
|
|
|
|
|
The `RowCallbackHandler` interface extracts values from each row of a `ResultSet`.
|
|
|
|
|
|
|
|
|
|
The `CqlTemplate` can be used within a DAO implementation through direct instantiation with a `SessionFactory` reference or be configured in the Spring container and given to DAOs as a bean reference. `CqlTemplate` is a foundational building block for <<cassandra-template,`CassandraTemplate`>>.
|
|
|
|
|
@@ -1118,3 +1118,78 @@ The terminating methods (`first()`, `one()`, `all()`, and `stream()`) handle swi
|
|
|
|
|
WARNING: 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).
|
|
|
|
|
|
|
|
|
|
[[cassandra.template.prepared-statements]]
|
|
|
|
|
== Prepared Statements
|
|
|
|
|
|
|
|
|
|
CQL statements that are executed multiple times can be prepared and stored in a `PreparedStatement` object to improve query performance.
|
|
|
|
|
Both, the driver and Cassandra maintain a mapping of `PreparedStatement` queries to their metadata.
|
|
|
|
|
You can use prepared statements through the following abstractions:
|
|
|
|
|
|
|
|
|
|
* `CqlTemplate` through the choice of API
|
|
|
|
|
* `CassandraTemplate` by enabling prepared statements
|
|
|
|
|
* Cassandra repositories as they are built on `CassandraTemplate`
|
|
|
|
|
|
|
|
|
|
[[cassandra.template.prepared-statements.cql]]
|
|
|
|
|
=== Using `CqlTemplate`
|
|
|
|
|
|
|
|
|
|
The `CqlTemplate` class (and its asynchronous and reactive variants) offers various methods accepting static CQL, `Statement` objects and `PreparedStatementCreator`.
|
|
|
|
|
Methods accepting static CQL without additional arguments typically run the CQL statement as-is without further processing.
|
|
|
|
|
Methods accepting static CQL in combination with an arguments array (such as `execute(String cql, Object... args)` and `queryForRows(String cql, Object... args)`) use prepared statements.
|
|
|
|
|
Internally, these methods create a `PreparedStatementCreator` and `PreparedStatementBinder` objects to prepare the statement and later on to bind values to the statement to run it.
|
|
|
|
|
Spring Data Cassandra generally uses index-based parameter bindings for prepared statements.
|
|
|
|
|
|
|
|
|
|
Since Cassandra Driver version 4, prepared statements are cached on the driver level which removes the need to keep track of prepared statements in the application.
|
|
|
|
|
|
|
|
|
|
The following example shows how to issue a query with a parametrized prepared statement:
|
|
|
|
|
|
|
|
|
|
====
|
|
|
|
|
[source,java,indent=0]
|
|
|
|
|
----
|
|
|
|
|
include::../{example-root}/CqlTemplateExamples.java[tags=lastName]
|
|
|
|
|
----
|
|
|
|
|
====
|
|
|
|
|
|
|
|
|
|
In cases where you require more control over statement preparation and parameter binding (for example, using named binding parameters), you can fully control prepared statement creation and parameter binding by calling query methods with `PreparedStatementCreator` and `PreparedStatementBinder` arguments:
|
|
|
|
|
|
|
|
|
|
====
|
|
|
|
|
[source,java,indent=0]
|
|
|
|
|
----
|
|
|
|
|
include::../{example-root}/CqlTemplateExamples.java[tags=preparedStatement]
|
|
|
|
|
----
|
|
|
|
|
====
|
|
|
|
|
|
|
|
|
|
Spring Data Cassandra ships with classes supporting that pattern in the `cql` package:
|
|
|
|
|
|
|
|
|
|
* `SimplePreparedStatementCreator` - utility class to create a prepared statement.
|
|
|
|
|
* `ArgumentPreparedStatementBinder` - utility class to bind arguments to a prepared statement.
|
|
|
|
|
|
|
|
|
|
[[cassandra.template.prepared-statements.cassandra-template]]
|
|
|
|
|
=== Using `CassandraTemplate`
|
|
|
|
|
|
|
|
|
|
The `CassandraTemplate` class is built on top of `CqlTemplate` to provide a higher level of abstraction.
|
|
|
|
|
The use of prepared statements can be controlled directly on `CassandraTemplate` (and its asynchronous and reactive variants) by calling `setUsePreparedStatements(false)` respective `setUsePreparedStatements(true)`.
|
|
|
|
|
Note that the use of prepared statements by `CassandraTemplate` is enabled by default.
|
|
|
|
|
|
|
|
|
|
The following example shows the use of methods that generate and that accept CQL:
|
|
|
|
|
|
|
|
|
|
====
|
|
|
|
|
[source,java,indent=0]
|
|
|
|
|
----
|
|
|
|
|
include::../{example-root}/CassandraTemplateExamples.java[tags=preparedStatement]
|
|
|
|
|
----
|
|
|
|
|
====
|
|
|
|
|
|
|
|
|
|
Calling entity-bound methods such as `select(Query, Class<T>)` or `update(Query, Update, Class<T>)` build CQL statements themselves to perform the intended operations.
|
|
|
|
|
Some `CassandraTemplate` methods (such as `select(Statement<?>, Class<T>)`) also accepts CQL `Statement` objects as part of their API.
|
|
|
|
|
|
|
|
|
|
It's possible to participate in prepared statements when calling methods accepting a `Statement` with a `SimpleStatement` object.
|
|
|
|
|
The template API extracts the query string and parameters (positional and named parameters) and uses these to prepare, bind, and run the statement.
|
|
|
|
|
Non-``SimpleStatement`` objects cannot be used with prepared statements.
|
|
|
|
|
|
|
|
|
|
[[cassandra.template.prepared-statements.caching]]
|
|
|
|
|
=== Caching Prepared Statements
|
|
|
|
|
|
|
|
|
|
Since Cassandra driver 4.0, prepared statements are cached by the `CqlSession` cache so it is okay to prepare the same string twice.
|
|
|
|
|
Previous versions required caching of prepared statements outside of the driver.
|
|
|
|
|
See also the https://docs.datastax.com/en/developer/java-driver/latest/manual/core/statements/prepared/[Driver documentation on Prepared Statements] for further reference.
|
|
|
|
|
|