diff --git a/src/docbkx/reference/cassandra.xml b/src/docbkx/reference/cassandra.xml index b16e9bd22..94e4894cd 100644 --- a/src/docbkx/reference/cassandra.xml +++ b/src/docbkx/reference/cassandra.xml @@ -449,19 +449,279 @@ private CassandraOperations cassandraOperations; Cassandra requires that you have at least 1 Partition Key field for a CQL Table. Alternately, you can have one or more Clustering Key - fields. + fields. When your CQL Table has a composite Primary Key field you must + create a @PrimaryKeyClass to define the structure of the composite PK. + In this context, composite PK means one or more partition columns, or 1 + partition column plus one or more clustering columns. + +
+ Simplest Composite Key + + The simplest for of a Composite key is a key with one partition + key and one clustering key. Here is an example of a CQL Table, and the + corresponding POJOs that represent the table and it's composite + key. + + CQL Table defined in Cassandra + + create table login_event( + person_id text, + event_time timestamp, + event_code int, + ip_address text, + primary key (person_id, event_time)) + with CLUSTERING ORDER BY (event_time DESC) +; + + Class defining the Composite Primary Key. + NOTE: PrimaryKeyClass must implement + Serializable and provide implementation of + hashCode() and equals() just + like the example. + + package org.spring.cassandra.example; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.cassandra.core.Ordering; +import org.springframework.cassandra.core.PrimaryKeyType; +import org.springframework.data.cassandra.mapping.PrimaryKeyClass; +import org.springframework.data.cassandra.mapping.PrimaryKeyColumn; + +@PrimaryKeyClass +public class LoginEventKey implements Serializable { + + @PrimaryKeyColumn(name = "person_id", ordinal = 0, type = PrimaryKeyType.PARTITIONED) + private String personId; + + @PrimaryKeyColumn(name = "event_time", ordinal = 1, type = PrimaryKeyType.CLUSTERED, ordering = Ordering.DESCENDING) + private Date eventTime; + + public String getPersonId() { + return personId; + } + + public void setPersonId(String personId) { + this.personId = personId; + } + + public Date getEventTime() { + return eventTime; + } + + public void setEventTime(Date eventTime) { + this.eventTime = eventTime; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((eventTime == null) ? 0 : eventTime.hashCode()); + result = prime * result + ((personId == null) ? 0 : personId.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + LoginEventKey other = (LoginEventKey) obj; + if (eventTime == null) { + if (other.eventTime != null) + return false; + } else if (!eventTime.equals(other.eventTime)) + return false; + if (personId == null) { + if (other.personId != null) + return false; + } else if (!personId.equals(other.personId)) + return false; + return true; + } +} + + + Class defining the CQL Table, having the Composite + Primary Key as an attribute and annotated as the + PrimaryKey. + + package org.spring.cassandra.example; + +import org.springframework.data.cassandra.mapping.Column; +import org.springframework.data.cassandra.mapping.PrimaryKey; +import org.springframework.data.cassandra.mapping.Table; + +@Table(value = "login_event") +public class LoginEvent { + + @PrimaryKey + private LoginEventKey pk; + + @Column(value = "event_code") + private int eventCode; + + @Column(value = "ip_address") + private String ipAddress; + + public LoginEventKey getPk() { + return pk; + } + + public void setPk(LoginEventKey pk) { + this.pk = pk; + } + + public int getEventCode() { + return eventCode; + } + + public void setEventCode(int eventCode) { + this.eventCode = eventCode; + } + + public String getIpAddress() { + return ipAddress; + } + + public void setIpAddress(String ipAddress) { + this.ipAddress = ipAddress; + } + +} + +
+ +
+ Complex Composite Primary Key + + The annotations provided with Spring Data Cassandra can handle + any key combination available in Cassandra. Here is one more example + of a Composite Primary Key with 5 columns, 2 of which are a composite + partition key, and the remaining 3 are ordered clustering keys. The + getters/setters, hashCode and equals are omitted for brevity. + + package org.spring.cassandra.example; + +import java.io.Serializable; +import java.util.Date; + +import org.springframework.cassandra.core.Ordering; +import org.springframework.cassandra.core.PrimaryKeyType; +import org.springframework.data.cassandra.mapping.PrimaryKeyClass; +import org.springframework.data.cassandra.mapping.PrimaryKeyColumn; + +@PrimaryKeyClass +public class DetailedLoginEventKey implements Serializable { + + @PrimaryKeyColumn(name = "person_id", ordinal = 0, type = PrimaryKeyType.PARTITIONED) + private String personId; + + @PrimaryKeyColumn(name = "wks_id", ordinal = 1, type = PrimaryKeyType.PARTITIONED) + private String workstationId; + + @PrimaryKeyColumn(ordinal = 2, type = PrimaryKeyType.CLUSTERED, ordering = Ordering.ASCENDING) + private Date application; + + @PrimaryKeyColumn(name = "event_code", ordinal = 3, type = PrimaryKeyType.CLUSTERED, ordering = Ordering.ASCENDING) + private Date eventCode; + + @PrimaryKeyColumn(name = "event_time", ordinal = 4, type = PrimaryKeyType.CLUSTERED, ordering = Ordering.DESCENDING) + private Date eventTime; + + ... + +} + +
Type mapping - TODO With Examples + Spring Data Cassandra relies on the DataStax Java Driver type + mapping component. This approach ensures that as types are added or + changed, the Spring Data Cassandra module will continue to function + without requiring changes. For more information on the DataStax CQL3 to + Java Type mappings, please see their Documentation + here.
Methods for saving and inserting rows - TODO With Examples +
+ Single records inserts + + To insert one row at a time, there are many options. At this + point you should already have a cassandraTemplate available to you so + we will just how the relevant code for each section, omitting the + template setup. + + Insert a record with an annotated POJO. + + cassandraOperations.insert(new Person("123123123", "Alison", 39)); + + Insert a row using the QueryBuilder.Insert object that is part + of the DataStax Java Driver. + + Insert insert = QueryBuilder.insertInto("person"); +insert.setConsistencyLevel(ConsistencyLevel.ONE); +insert.value("id", "123123123"); +insert.value("name", "Alison"); +insert.value("age", 39); + +cassandraOperations.execute(insert); + + Then there is always the old fashioned way. You can write your + own CQL statements. + + String cql = "insert into person (id, name, age) values ('123123123', 'Alison', 39)"; + +cassandraOperations.execute(cql); +
+ +
+ Multiple inserts for high speed ingestion + + CQLOperations, which is extended by CassandraOperations is a + lower level Template that you can use for just about anything you need + to accomplish with Cassandra. CqlOperations includes several + overloaded methods named ingest(). + + Use these methods to pass a CQL String with Bind Markers, and + your preferred flavor of data set (Object[][] and + List<List<T>>). + + The ingest method takes advantage of static PreparedStatements + that are only prepared once for performance. Each record in your data + list is bound to the same PreparedStatement, then executed + asynchronously for high performance. + + String cqlIngest = "insert into person (id, name, age) values (?, ?, ?)"; + + List<Object> person1 = new ArrayList<Object>(); + person1.add("10000"); + person1.add("David"); + person1.add(40); + + List<Object> person2 = new ArrayList<Object>(); + person2.add("10001"); + person2.add("Roger"); + person2.add(65); + + List<List<?>> people = new ArrayList<List<?>>(); + people.add(person1); + people.add(person2); + + cassandraOperations.ingest(cqlIngest, people); +
@@ -470,15 +730,6 @@ private CassandraOperations cassandraOperations; TODO With Examples
-
- Upserting rows in a CQL table - - To upsert a row in Cassandra, use the insert logic explained in - the previous section. When you insert a row into Cassandra, and there is - already a row for that primary key value, the row is overwritten by the - data in the new insert. -
-
Methods for removing rows