Using the CassandraTemplate from Spring Data

1. Overview

This is the second article of the Spring Data Cassandra article series. In this article we will mainly focus on CassandraTemplate and CQL queries in the data access layer. You can read more about Spring Data Cassandra in the first article in the series.

Cassandra Query Language (CQL) is the query language for the Cassandra database and CqlTemplate is the low-level data access template in Spring Data Cassandra – it conveniently exposes data manipulation related operations to execute CQL statements.

CassandraTemplate builds on top of the low level CqlTemplate and provides a simple way to query domain objects and map the objects to a persisted data structure in Cassandra.

Let’s start with the configuration and then dive into examples of using the two templates.

[[cassandraTemplate ]]
=== 2. CassandraTemplate Configuration

[[cassandraTemplate ]]CassandraTemplate is available in the Spring context because our main Cassandra Spring config is extending AbstractCassandraConfiguration:

@Configuration
@EnableCassandraRepositories(basePackages = "org.baeldung.spring.data.cassandra.repository")
public class CassandraConfig extends AbstractCassandraConfiguration { ... }

We can then simple wire in the template – either by its exact type, CassandraTemplate, or as the more generic interface CassandraOperations:

@Autowired
private CassandraOperations cassandraTemplate;

3. Data Access Using CassandraTemplate

Let’s use the CassandraTemplate defined above in our data access layer module to work with data persistent.

3.1. Saving a New Book

We can save a new book to our book store:

Book javaBook = new Book(
  UUIDs.timeBased(), "Head First Java", "O'Reilly Media",
  ImmutableSet.of("Computer", "Software"));
cassandraTemplate.insert(javaBook);

Then we can check the availability of the inserted book in the database:

Select select = QueryBuilder.select().from("book")
  .where(QueryBuilder.eq("title", "Head First Java"))
  .and(QueryBuilder.eq("publisher", "O'Reilly Media"));
Book retrievedBook = cassandraTemplate.selectOne(select, Book.class);

We are using a Select QueryBuilder here, to be mapped to the selectOne() in cassandraTemplate. We will discuss the QueryBuilder in more depth in the CQL queries section.

3.2. Saving Multiple Books

We can save multiple books to our book store at once using a list:

Book javaBook = new Book(
  UUIDs.timeBased(), "Head First Java", "O'Reilly Media",
  ImmutableSet.of("Computer", "Software"));
Book dPatternBook = new Book(
  UUIDs.timeBased(), "Head Design Patterns", "O'Reilly Media",
  ImmutableSet.of("Computer", "Software"));
List<Book> bookList = new ArrayList<Book>();
bookList.add(javaBook);
bookList.add(dPatternBook);
cassandraTemplate.insert(bookList);

3.3. Updating an Existing Book

Lat’s start by inserting a new book:

Book javaBook = new Book(
  UUIDs.timeBased(), "Head First Java", "O'Reilly Media",
  ImmutableSet.of("Computer", "Software"));
cassandraTemplate.insert(javaBook);

Let’s fetch the book:

Select select = QueryBuilder.select().from("book");
Book retrievedBook = cassandraTemplate.selectOne(select, Book.class);

Then let’s add some additional tags to the retrieved book:

retrievedBook.setTags(ImmutableSet.of("Java", "Programming"));
cassandraTemplate.update(retrievedBook);

3.4. Deleting an Inserted Book

Let’s insert a new book:

Book javaBook = new Book(
  UUIDs.timeBased(), "Head First Java", "O'Reilly Media",
  ImmutableSet.of("Computer", "Software"));
cassandraTemplate.insert(javaBook);

Then delete the book:

cassandraTemplate.delete(javaBook);

3.5. Deleting All Books

Let’s now insert some new books:

Book javaBook = new Book(
  UUIDs.timeBased(), "Head First Java", "O'Reilly Media",
  ImmutableSet.of("Computer", "Software"));
Book dPatternBook = new Book(
  UUIDs.timeBased(), "Head Design Patterns", "O'Reilly Media",
  ImmutableSet.of("Computer", "Software"));
cassandraTemplate.insert(javaBook);
cassandraTemplate.insert(dPatternBook);

Then delete the all the books:

cassandraTemplate.deleteAll(Book.class);

4. Data Access Using CQL Queries

It is always possible to use CQL queries for data manipulation in the data access layer. CQL query handing is performed by the CqlTemplate class, allowing us to execute custom queries as required.

However, as CassandraTemplate class is an extension of CqlTemplate, we can use it directly to execute those queries.

Let’s look at the different methods we can use to manipulate data using CQL queries.

4.1. Using QueryBuilder

QueryBuilder can be used to build a query for data manipulation in database. Almost all the standard manipulations can be built up using the out-of-the-box building blocks:

Insert insertQueryBuider = QueryBuilder.insertInto("book")
 .value("isbn", UUIDs.timeBased())
 .value("title", "Head First Java")
 .value("publisher", "OReilly Media")
 .value("tags", ImmutableSet.of("Software"));
cassandraTemplate.execute(insertQueryBuider);

If you look closely at the code snippet, you may notice that the execute() method is used instead of the relevant operation type (insert, delete, etc.). This is because the type of query is defined by the output of the QueryBuilder.

4.2. Using PreparedStatements

Even though PreparedStatements can be used for any case, this mechanism is usually recommended for multiple inserts for high-speed ingestion.

A PreparedStatement is prepared only once, helping ensure high performance:

UUID uuid = UUIDs.timeBased();
String insertPreparedCql =
  "insert into book (isbn, title, publisher, tags) values (?, ?, ?, ?)";
List<Object> singleBookArgsList = new ArrayList<>();
List<List<?>> bookList = new ArrayList<>();
singleBookArgsList.add(uuid);
singleBookArgsList.add("Head First Java");
singleBookArgsList.add("OReilly Media");
singleBookArgsList.add(ImmutableSet.of("Software"));
bookList.add(singleBookArgsList);
cassandraTemplate.ingest(insertPreparedCql, bookList);

4.3. Using CQL Statements

We can directly use CQL statements to query data as follows:

UUID uuid = UUIDs.timeBased();
String insertCql = "insert into book (isbn, title, publisher, tags)
  values (" + uuid + ", 'Head First Java', 'OReilly Media', {'Software'})";
cassandraTemplate.execute(insertCql);

5. Conclusion

In this article, we examined various data manipulation strategies using Spring Data Cassandra, including CassandraTemplate and CQL queries.

The implementation of the above code snippets and examples can be found in my GitHub project – this is a Maven-based project, so it should be easy to import and run as it is.

Leave a Reply

Your email address will not be published.