DATACASS-32 : WIP : Completed PreparedStatement Operations.
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cassandra.core;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.PreparedStatement;
|
||||
import com.datastax.driver.core.Session;
|
||||
import com.datastax.driver.core.exceptions.DriverException;
|
||||
|
||||
/**
|
||||
* Created a PreparedStatement and retrieved the PreparedStatement from cache if the statement has been prepared
|
||||
* previously. In general, this creator should be used over the {@link SimplePreparedStatementCreator} as it provides
|
||||
* better performance.
|
||||
*
|
||||
* <p>
|
||||
* There is overhead in Cassandra when Preparing a Statement. This is negligible on a single data center configuration,
|
||||
* but when your cluster spans multiple data centers, preparing the same statement over and over again is not necessary
|
||||
* and causes performance issues in high throughput use cases.
|
||||
* </p>
|
||||
*
|
||||
* @author David Webb
|
||||
*
|
||||
*/
|
||||
public class CachedPreparedStatementCreator implements PreparedStatementCreator, CqlProvider {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(CachedPreparedStatementCreator.class);
|
||||
|
||||
private final String cql;
|
||||
|
||||
private PreparedStatement cache;
|
||||
|
||||
/**
|
||||
* Create a CachedPreparedStatementCreator from the provided CQL.
|
||||
*
|
||||
* @param cql
|
||||
*/
|
||||
public CachedPreparedStatementCreator(String cql) {
|
||||
Assert.notNull(cql, "CQL is required to create a PreparedStatement");
|
||||
this.cql = cql;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.PreparedStatementCreator#createPreparedStatement(com.datastax.driver.core.Session)
|
||||
*/
|
||||
@Override
|
||||
public PreparedStatement createPreparedStatement(Session session) throws DriverException {
|
||||
if (cache == null) {
|
||||
log.debug("PreparedStatement cache is null, preparing new Statement");
|
||||
cache = session.prepare(getCql());
|
||||
} else {
|
||||
log.debug("Using cached PreparedStatement");
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CqlProvider#getCql()
|
||||
*/
|
||||
@Override
|
||||
public String getCql() {
|
||||
return this.cql;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cassandra.core;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
/**
|
||||
* @author David Webb
|
||||
*
|
||||
*/
|
||||
public class CqlParameter {
|
||||
|
||||
/** The name of the parameter, if any */
|
||||
private String name;
|
||||
|
||||
/** SQL type constant from {@link DataType} */
|
||||
private final DataType type;
|
||||
|
||||
/** The scale to apply in case of a NUMERIC or DECIMAL type, if any */
|
||||
private Integer scale;
|
||||
|
||||
/**
|
||||
* Create a new anonymous CqlParameter, supplying the SQL type.
|
||||
*
|
||||
* @param type Cassandra Data Type of the parameter according to {@link DataType}
|
||||
*/
|
||||
public CqlParameter(DataType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new anonymous CqlParameter, supplying the SQL type.
|
||||
*
|
||||
* @param type Cassandra Data Type of the parameter according to {@link DataType}
|
||||
* @param scale the number of digits after the decimal point
|
||||
*/
|
||||
public CqlParameter(DataType type, int scale) {
|
||||
this.type = type;
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CqlParameter, supplying name and SQL type.
|
||||
*
|
||||
* @param name name of the parameter, as used in input and output maps
|
||||
* @param type Cassandra Data Type of the parameter according to {@link DataType}
|
||||
*/
|
||||
public CqlParameter(String name, DataType type) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CqlParameter, supplying name and SQL type.
|
||||
*
|
||||
* @param name name of the parameter, as used in input and output maps
|
||||
* @param type Cassandra Data Type of the parameter according to {@link DataType}
|
||||
* @param scale the number of digits after the decimal point (for DECIMAL and NUMERIC types)
|
||||
*/
|
||||
public CqlParameter(String name, DataType type, int scale) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*
|
||||
* @param otherParam the CqlParameter object to copy from
|
||||
*/
|
||||
public CqlParameter(CqlParameter otherParam) {
|
||||
Assert.notNull(otherParam, "CqlParameter object must not be null");
|
||||
this.name = otherParam.name;
|
||||
this.type = otherParam.type;
|
||||
this.scale = otherParam.scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the parameter.
|
||||
*/
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the SQL type of the parameter.
|
||||
*/
|
||||
public DataType getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the scale of the parameter, if any.
|
||||
*/
|
||||
public Integer getScale() {
|
||||
return this.scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether this parameter holds input values that should be set before execution even if they are {@code null}.
|
||||
* <p>
|
||||
* This implementation always returns {@code true}.
|
||||
*/
|
||||
public boolean isInputValueProvided() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a list of JDBC types, as defined in {@code java.sql.Types}, to a List of CqlParameter objects as used in
|
||||
* this package.
|
||||
*/
|
||||
public static List<CqlParameter> sqlTypesToAnonymousParameterList(DataType[] types) {
|
||||
List<CqlParameter> result = new LinkedList<CqlParameter>();
|
||||
if (types != null) {
|
||||
for (DataType type : types) {
|
||||
result.add(new CqlParameter(type));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cassandra.core;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
/**
|
||||
* @author David Webb
|
||||
*
|
||||
*/
|
||||
public class CqlParameterValue extends CqlParameter {
|
||||
|
||||
private final Object value;
|
||||
|
||||
/**
|
||||
* Create a new CqlParameterValue, supplying the Cassandra DataType.
|
||||
*
|
||||
* @param type Cassandra Data Type of the parameter according to {@link DataType}
|
||||
* @param value the value object
|
||||
*/
|
||||
public CqlParameterValue(DataType type, Object value) {
|
||||
super(type);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CqlParameterValue, supplying the Cassandra DataType.
|
||||
*
|
||||
* @param type Cassandra Data Type of the parameter according to {@link DataType}
|
||||
* @param scale the number of digits after the decimal point (for DECIMAL and NUMERIC types)
|
||||
* @param value the value object
|
||||
*/
|
||||
public CqlParameterValue(DataType type, int scale, Object value) {
|
||||
super(type, scale);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CqlParameterValue based on the given CqlParameter declaration.
|
||||
*
|
||||
* @param declaredParam the declared CqlParameter to define a value for
|
||||
* @param value the value object
|
||||
*/
|
||||
public CqlParameterValue(CqlParameter declaredParam, Object value) {
|
||||
super(declaredParam);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value object that this parameter value holds.
|
||||
*/
|
||||
public Object getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cassandra.core;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author David Webb
|
||||
*
|
||||
*/
|
||||
public class PreparedStatementCreatorFactory {
|
||||
|
||||
/**
|
||||
* The CQL, which won't change when the parameters change
|
||||
*/
|
||||
private final String cql;
|
||||
|
||||
/** List of CqlParameter objects. May not be {@code null}. */
|
||||
private final List<CqlParameter> declaredParameters;
|
||||
|
||||
/**
|
||||
* Create a new factory.
|
||||
*/
|
||||
public PreparedStatementCreatorFactory(String cql) {
|
||||
this.cql = cql;
|
||||
this.declaredParameters = new LinkedList<CqlParameter>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new factory with the given CQL and parameters.
|
||||
*
|
||||
* @param cql CQL
|
||||
* @param declaredParameters list of {@link CqlParameter} objects
|
||||
* @see CqlParameter
|
||||
*/
|
||||
public PreparedStatementCreatorFactory(String cql, List<CqlParameter> declaredParameters) {
|
||||
this.cql = cql;
|
||||
this.declaredParameters = declaredParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new PreparedStatementBinder for the given parameters.
|
||||
*
|
||||
* @param params list of parameters (may be {@code null})
|
||||
*/
|
||||
public PreparedStatementBinder newPreparedStatementBinder(List<CqlParameterValue> params) {
|
||||
return new PreparedStatementCreatorImpl(params != null ? params : Collections.emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new PreparedStatementBinder for the given parameters.
|
||||
*
|
||||
* @param params the parameter array (may be {@code null})
|
||||
*/
|
||||
public PreparedStatementBinder newPreparedStatementBinder(Object[] params) {
|
||||
return new PreparedStatementCreatorImpl(params != null ? Arrays.asList(params) : Collections.emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new PreparedStatementCreator for the given parameters.
|
||||
*
|
||||
* @param params list of parameters (may be {@code null})
|
||||
*/
|
||||
public PreparedStatementCreator newPreparedStatementCreator(List<CqlParameterValue> params) {
|
||||
return new PreparedStatementCreatorImpl(params != null ? params : Collections.emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new PreparedStatementCreator for the given parameters.
|
||||
*
|
||||
* @param params the parameter array (may be {@code null})
|
||||
*/
|
||||
public PreparedStatementCreator newPreparedStatementCreator(Object[] params) {
|
||||
return new PreparedStatementCreatorImpl(params != null ? Arrays.asList(params) : Collections.emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new PreparedStatementCreator for the given parameters.
|
||||
*
|
||||
* @param sqlToUse the actual SQL statement to use (if different from the factory's, for example because of named
|
||||
* parameter expanding)
|
||||
* @param params the parameter array (may be {@code null})
|
||||
*/
|
||||
public PreparedStatementCreator newPreparedStatementCreator(String sqlToUse, Object[] params) {
|
||||
return new PreparedStatementCreatorImpl(sqlToUse, params != null ? Arrays.asList(params) : Collections.emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
* PreparedStatementCreator implementation returned by this class.
|
||||
*/
|
||||
private class PreparedStatementCreatorImpl implements PreparedStatementCreator, PreparedStatementBinder, CqlProvider {
|
||||
|
||||
private final String actualCql;
|
||||
|
||||
private final List<?> parameters;
|
||||
|
||||
public PreparedStatementCreatorImpl(List<?> parameters) {
|
||||
this(cql, parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param actualCql
|
||||
* @param parameters
|
||||
*/
|
||||
public PreparedStatementCreatorImpl(String actualCql, List<?> parameters) {
|
||||
this.actualCql = actualCql;
|
||||
Assert.notNull(parameters, "Parameters List must not be null");
|
||||
this.parameters = parameters;
|
||||
if (this.parameters.size() != declaredParameters.size()) {
|
||||
Set<String> names = new HashSet<String>();
|
||||
for (int i = 0; i < parameters.size(); i++) {
|
||||
Object param = parameters.get(i);
|
||||
if (param instanceof CqlParameterValue) {
|
||||
names.add(((CqlParameterValue) param).getName());
|
||||
} else {
|
||||
names.add("Parameter #" + i);
|
||||
}
|
||||
}
|
||||
if (names.size() != declaredParameters.size()) {
|
||||
throw new InvalidDataAccessApiUsageException("CQL [" + cql + "]: given " + names.size()
|
||||
+ " parameters but expected " + declaredParameters.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.PreparedStatementCreator#createPreparedStatement(com.datastax.driver.core.Session)
|
||||
*/
|
||||
@Override
|
||||
public PreparedStatement createPreparedStatement(Session session) throws DriverException {
|
||||
return session.prepare(this.actualCql);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.PreparedStatementBinder#bindValues(com.datastax.driver.core.PreparedStatement)
|
||||
*/
|
||||
@Override
|
||||
public BoundStatement bindValues(PreparedStatement ps) throws DriverException {
|
||||
if (this.parameters == null || this.parameters.size() == 0) {
|
||||
return ps.bind();
|
||||
}
|
||||
|
||||
// Test the type of the first value
|
||||
Object v = this.parameters.get(0);
|
||||
Object[] values;
|
||||
if (v instanceof CqlParameterValue) {
|
||||
LinkedList<Object> valuesList = new LinkedList<Object>();
|
||||
for (Object value : this.parameters) {
|
||||
valuesList.add(((CqlParameterValue) value).getValue());
|
||||
}
|
||||
values = valuesList.toArray();
|
||||
} else {
|
||||
values = this.parameters.toArray();
|
||||
}
|
||||
|
||||
return ps.bind(values);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CqlProvider#getCql()
|
||||
*/
|
||||
@Override
|
||||
public String getCql() {
|
||||
return cql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("PreparedStatementCreatorFactory.PreparedStatementCreatorImpl: cql=[");
|
||||
sb.append(cql).append("]; parameters=").append(this.parameters);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -77,5 +77,4 @@ public class TestConfig extends AbstractCassandraConfiguration {
|
||||
return template;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -90,4 +90,15 @@ public class Book {
|
||||
this.pages = pages;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("isbn -> " + isbn).append("\n");
|
||||
sb.append("tile -> " + title).append("\n");
|
||||
sb.append("author -> " + author).append("\n");
|
||||
sb.append("pages -> " + pages).append("\n");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,15 +41,31 @@ import org.junit.runner.RunWith;
|
||||
import org.slf4j.Logger;
|
||||
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.CachedPreparedStatementCreator;
|
||||
import org.springframework.cassandra.core.CassandraOperations;
|
||||
import org.springframework.cassandra.core.CqlParameter;
|
||||
import org.springframework.cassandra.core.CqlParameterValue;
|
||||
import org.springframework.cassandra.core.HostMapper;
|
||||
import org.springframework.cassandra.core.PreparedStatementBinder;
|
||||
import org.springframework.cassandra.core.PreparedStatementCreatorFactory;
|
||||
import org.springframework.cassandra.core.ResultSetExtractor;
|
||||
import org.springframework.cassandra.core.RingMember;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.cassandra.test.integration.config.TestConfig;
|
||||
import org.springframework.data.cassandra.test.integration.table.Book;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
|
||||
import com.datastax.driver.core.BoundStatement;
|
||||
import com.datastax.driver.core.DataType;
|
||||
import com.datastax.driver.core.Host;
|
||||
import com.datastax.driver.core.PreparedStatement;
|
||||
import com.datastax.driver.core.ResultSet;
|
||||
import com.datastax.driver.core.Row;
|
||||
import com.datastax.driver.core.Session;
|
||||
import com.datastax.driver.core.exceptions.DriverException;
|
||||
|
||||
/**
|
||||
@@ -84,8 +100,9 @@ public class CassandraOperationsTest {
|
||||
private final static int CASSANDRA_THRIFT_PORT = 9160;
|
||||
|
||||
@Rule
|
||||
public CassandraCQLUnit cassandraCQLUnit = new CassandraCQLUnit(new ClassPathCQLDataSet("cql-dataload.cql",
|
||||
KEYSPACE_NAME), CASSANDRA_CONFIG, CASSANDRA_HOST, CASSANDRA_NATIVE_PORT);
|
||||
public CassandraCQLUnit cassandraCQLUnit = new CassandraCQLUnit(new ClassPathCQLDataSet(
|
||||
"cassandraOperationsTest-cql-dataload.cql", KEYSPACE_NAME), CASSANDRA_CONFIG, CASSANDRA_HOST,
|
||||
CASSANDRA_NATIVE_PORT);
|
||||
|
||||
@BeforeClass
|
||||
public static void startCassandra() throws IOException, TTransportException, ConfigurationException,
|
||||
@@ -146,6 +163,129 @@ public class CassandraOperationsTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preparedStatementFactoryTest() {
|
||||
|
||||
String cql = "select * from book where isbn = ?";
|
||||
|
||||
List<CqlParameter> parameters = new LinkedList<CqlParameter>();
|
||||
parameters.add(new CqlParameter("isbn", DataType.text()));
|
||||
|
||||
PreparedStatementCreatorFactory factory = new PreparedStatementCreatorFactory(cql, parameters);
|
||||
|
||||
List<CqlParameterValue> values = new LinkedList<CqlParameterValue>();
|
||||
values.add(new CqlParameterValue(DataType.text(), "999999999"));
|
||||
|
||||
Book b = cassandraTemplate.query(factory.newPreparedStatementCreator(values),
|
||||
factory.newPreparedStatementBinder(values), new ResultSetExtractor<Book>() {
|
||||
|
||||
@Override
|
||||
public Book extractData(ResultSet rs) throws DriverException, DataAccessException {
|
||||
Row r = rs.one();
|
||||
Book b = new Book();
|
||||
b.setIsbn(r.getString("isbn"));
|
||||
b.setTitle(r.getString("title"));
|
||||
b.setAuthor(r.getString("author"));
|
||||
b.setPages(r.getInt("pages"));
|
||||
return b;
|
||||
}
|
||||
});
|
||||
|
||||
log.info(b.toString());
|
||||
|
||||
}
|
||||
|
||||
// @Test
|
||||
public void cachedPreparedStatementTest() {
|
||||
|
||||
log.info(echoString("Hello"));
|
||||
log.info(echoString("Hello"));
|
||||
|
||||
String cql = "select * from book where isbn = ?";
|
||||
|
||||
CachedPreparedStatementCreator cpsc = new CachedPreparedStatementCreator(cql);
|
||||
|
||||
Book b = cassandraTemplate.query(cpsc, new PreparedStatementBinder() {
|
||||
|
||||
@Override
|
||||
public BoundStatement bindValues(PreparedStatement ps) throws DriverException {
|
||||
return ps.bind("999999999");
|
||||
}
|
||||
}, new ResultSetExtractor<Book>() {
|
||||
|
||||
@Override
|
||||
public Book extractData(ResultSet rs) throws DriverException, DataAccessException {
|
||||
Row r = rs.one();
|
||||
Book b = new Book();
|
||||
b.setIsbn(r.getString("isbn"));
|
||||
b.setTitle(r.getString("title"));
|
||||
b.setAuthor(r.getString("author"));
|
||||
b.setPages(r.getInt("pages"));
|
||||
return b;
|
||||
}
|
||||
});
|
||||
|
||||
assertNotNull(b);
|
||||
|
||||
log.info(b.toString());
|
||||
|
||||
try {
|
||||
DefaultKeyGenerator generator = new DefaultKeyGenerator();
|
||||
|
||||
// TODO Why does method have to be public to work? Options?
|
||||
Object cacheKey = generator.generate(CachedPreparedStatementCreator.class,
|
||||
CachedPreparedStatementCreator.class.getMethod("getCachedPreparedStatement", Session.class, String.class),
|
||||
cassandraTemplate.getSession(), cql);
|
||||
|
||||
log.info("cacheKey -> " + cacheKey);
|
||||
|
||||
// ConcurrentMapCache cache = (ConcurrentMapCache) cacheManager.getCache("sdc-pstmts");
|
||||
// ConcurrentMap cacheMap = cache.getNativeCache();
|
||||
// assertNotNull(cacheMap);
|
||||
// log.info("CacheMap.size() -> " + cacheMap.size());
|
||||
// ValueWrapper vw = cache.get(cacheKey);
|
||||
// PreparedStatement pstmt = (PreparedStatement) vw.get();
|
||||
// assertNotNull(pstmt);
|
||||
// log.info(pstmt.getQueryString());
|
||||
// assertEquals(pstmt.getQueryString(), cql);
|
||||
} catch (NoSuchMethodException e) {
|
||||
log.error("Failed to find method", e);
|
||||
}
|
||||
|
||||
CachedPreparedStatementCreator cpsc2 = new CachedPreparedStatementCreator(cql);
|
||||
|
||||
Book b2 = cassandraTemplate.query(cpsc2, new PreparedStatementBinder() {
|
||||
|
||||
@Override
|
||||
public BoundStatement bindValues(PreparedStatement ps) throws DriverException {
|
||||
return ps.bind("999999999");
|
||||
}
|
||||
}, new ResultSetExtractor<Book>() {
|
||||
|
||||
@Override
|
||||
public Book extractData(ResultSet rs) throws DriverException, DataAccessException {
|
||||
Row r = rs.one();
|
||||
Book b = new Book();
|
||||
b.setIsbn(r.getString("isbn"));
|
||||
b.setTitle(r.getString("title"));
|
||||
b.setAuthor(r.getString("author"));
|
||||
b.setPages(r.getInt("pages"));
|
||||
return b;
|
||||
}
|
||||
});
|
||||
|
||||
assertNotNull(b2);
|
||||
|
||||
log.info(b2.toString());
|
||||
|
||||
}
|
||||
|
||||
@Cacheable("sdc-pstmts")
|
||||
public String echoString(String s) {
|
||||
log.info("In EchoString");
|
||||
return s;
|
||||
}
|
||||
|
||||
@After
|
||||
public void clearCassandra() {
|
||||
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
|
||||
@@ -154,6 +294,6 @@ public class CassandraOperationsTest {
|
||||
|
||||
@AfterClass
|
||||
public static void stopCassandra() {
|
||||
EmbeddedCassandraServerHelper.stopEmbeddedCassandra();
|
||||
// EmbeddedCassandraServerHelper.stopEmbeddedCassandra();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
create table book (isbn text, title text, author text, pages int, PRIMARY KEY (isbn));
|
||||
create table book_alt (isbn text, title text, author text, pages int, PRIMARY KEY (isbn));
|
||||
insert into book (isbn, title, author, pages) values ('999999999', 'Book of Nines', 'Nine Nine', 999);
|
||||
@@ -1,2 +1,3 @@
|
||||
create table book (isbn text, title text, author text, pages int, PRIMARY KEY (isbn));
|
||||
create table book_alt (isbn text, title text, author text, pages int, PRIMARY KEY (isbn));
|
||||
create table book_alt (isbn text, title text, author text, pages int, PRIMARY KEY (isbn));
|
||||
/*insert into book (isbn, title, author, pages) values ('999999999', 'Book of Nines', 'Nine Nine', 999);*/
|
||||
Reference in New Issue
Block a user