Created BoundStatementFactory for high performance write ingestion.

This commit is contained in:
David Webb
2013-11-23 01:02:55 -05:00
parent 3394c76b7d
commit c1dfebb822
5 changed files with 130 additions and 1 deletions

View File

@@ -15,6 +15,16 @@
*/
package org.springframework.cassandra.core;
import java.util.LinkedList;
import java.util.List;
import org.springframework.util.CollectionUtils;
import com.datastax.driver.core.BoundStatement;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.exceptions.DriverException;
/**
* <b>This is the primary class in core for binding many values to a Cassandra PreparedStatement.</b>
*
@@ -26,6 +36,91 @@ package org.springframework.cassandra.core;
* @author David Webb
*
*/
public class BoundStatementFactory {
public class BoundStatementFactory implements PreparedStatementCreator, CqlProvider {
private final String cql;
private PreparedStatement preparedStatement;
private List<List<?>> values = new LinkedList<List<?>>();
public BoundStatementFactory(String cql) {
this.cql = cql;
}
public void addValues(List<CqlParameterValue>... values) {
this.values.add(CollectionUtils.arrayToList(values));
}
public void addValues(Object[]... values) {
for (int i = 0; values != null && i < values.length; i++) {
this.values.add(CollectionUtils.arrayToList(values[i]));
}
}
public void replaceValues(List<CqlParameterValue>... values) {
this.values = CollectionUtils.arrayToList(values);
}
public void replaceValues(Object[]... values) {
noValues();
for (int i = 0; values != null && i < values.length; i++) {
this.values.add(CollectionUtils.arrayToList(values[i]));
}
}
public void noValues() {
this.values = new LinkedList<List<?>>();
}
/* (non-Javadoc)
* @see org.springframework.cassandra.core.CqlProvider#getCql()
*/
@Override
public String getCql() {
return this.cql;
}
/* (non-Javadoc)
* @see org.springframework.cassandra.core.PreparedStatementCreator#createPreparedStatement(com.datastax.driver.core.Session)
*/
@Override
public PreparedStatement createPreparedStatement(Session session) throws DriverException {
if (preparedStatement == null) {
preparedStatement = session.prepare(this.cql);
}
return preparedStatement;
}
/**
* Bind all values with the single CQL (PreparedStatement) and return BoundStatements read for execution.
*
* @return
* @throws DriverException
*/
public List<BoundStatement> bindValues() throws DriverException {
LinkedList<BoundStatement> boundStatements = new LinkedList<BoundStatement>();
for (List<?> list : this.values) {
// Test the type of the first value
Object v = list.get(0);
Object[] vls;
if (v instanceof CqlParameterValue) {
LinkedList<Object> valuesList = new LinkedList<Object>();
for (Object value : list) {
valuesList.add(((CqlParameterValue) value).getValue());
}
vls = valuesList.toArray();
} else {
vls = list.toArray();
}
boundStatements.add(preparedStatement.bind(vls));
}
return boundStatements;
}
}

View File

@@ -48,6 +48,8 @@ public interface CassandraOperations {
*/
void execute(final String cql) throws DataAccessException;
void execute(BoundStatementFactory bsf);
/**
* Executes the supplied CQL Query Asynchronously and returns nothing.
*

View File

@@ -559,4 +559,20 @@ public class CassandraTemplate extends CassandraAccessor implements CassandraOpe
}
});
}
/* (non-Javadoc)
* @see org.springframework.cassandra.core.CassandraOperations#execute(org.springframework.cassandra.core.BoundStatementFactory)
*/
@Override
public void execute(BoundStatementFactory bsf) {
bsf.createPreparedStatement(getSession());
List<BoundStatement> statements = bsf.bindValues();
for (BoundStatement bs : statements) {
getSession().execute(bs);
}
}
}

View File

@@ -33,6 +33,8 @@ import com.datastax.driver.core.exceptions.DriverException;
/**
* @author David Webb
*
* @deprecated - Pattern from JDBC Template, but DW doesn't like it. Use {@link BoundStatementFactory}
*
*/
public class PreparedStatementCreatorFactory {

View File

@@ -43,6 +43,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.interceptor.DefaultKeyGenerator;
import org.springframework.cassandra.core.BoundStatementFactory;
import org.springframework.cassandra.core.CachedPreparedStatementCreator;
import org.springframework.cassandra.core.CassandraOperations;
import org.springframework.cassandra.core.CqlParameter;
@@ -195,6 +196,19 @@ public class CassandraOperationsTest {
}
@Test
public void boundStatementFactoryTest() {
String cql = "insert into book (isbn, title, author, pages) values (?, ?, ?, ?)";
BoundStatementFactory bsf = new BoundStatementFactory(cql);
bsf.addValues(new Object[] { "1234", "Moby Dick", "Herman Manville", new Integer(456) }, new Object[] { "2345",
"War and Peace", "Russian Dude", new Integer(456) }, new Object[] { "3456", "Jane Ayre", "Charlotte",
new Integer(456) });
cassandraTemplate.execute(bsf);
}
// @Test
public void cachedPreparedStatementTest() {