具有多参数和多分区查询的Cassandra Bounder语句
在阅读了datastax博客中的“”一文后,我试图实现一个类似于“案例研究:多分区查询,又称“客户端选择…”一节中的解决方案 我目前有如下代码:具有多参数和多分区查询的Cassandra Bounder语句,cassandra,cql,datastax,datastax-java-driver,Cassandra,Cql,Datastax,Datastax Java Driver,在阅读了datastax博客中的“”一文后,我试图实现一个类似于“案例研究:多分区查询,又称“客户端选择…”一节中的解决方案 我目前有如下代码: public Future<List<ResultSet>> executeMultipleAsync(final BoundStatement statement, final Object... partitionKeys) { List<Future<ResultSet>> futures
public Future<List<ResultSet>> executeMultipleAsync(final BoundStatement statement, final Object... partitionKeys) {
List<Future<ResultSet>> futures = Lists.newArrayListWithExpectedSize(partitionKeys.length);
for (Object partitionKey : partitionKeys) {
Statement bs = statement.bind(partitionKey);
futures.add(executeWithRetry(bs));
}
return Futures.successfulAsList(futures);
}
SELECT * FROM <column_family_name> WHERE <param1> = :p1_name AND param2 = :p2_name AND <partiotion_key_name> = ?;
public Future executeMultipleAsync(final BoundStatement语句,final Object…partitionKeys){
List futures=Lists.newArrayListWithExpectedSize(partitionKeys.length);
for(对象分区键:分区键){
语句bs=Statement.bind(partitionKey);
添加(executeWithRetry(bs));
}
返回期货。成功列表(期货);
}
但是,我想对此进行改进。在这个BoundStatement持有的cql查询中,我希望有如下内容:
public Future<List<ResultSet>> executeMultipleAsync(final BoundStatement statement, final Object... partitionKeys) {
List<Future<ResultSet>> futures = Lists.newArrayListWithExpectedSize(partitionKeys.length);
for (Object partitionKey : partitionKeys) {
Statement bs = statement.bind(partitionKey);
futures.add(executeWithRetry(bs));
}
return Futures.successfulAsList(futures);
}
SELECT * FROM <column_family_name> WHERE <param1> = :p1_name AND param2 = :p2_name AND <partiotion_key_name> = ?;
从其中选择*=:p1_name和param2=:p2_name和=?;
我希望此方法的客户机为我提供一个具有已绑定参数(本例中为两个参数)的BoundStatement和分区键列表。在这种情况下,我所需要做的就是绑定分区键并执行查询。不幸的是,当我将键绑定到此语句时,我失败了,出现了一个错误-com.datasax.driver.core.exceptions.InvalidTypeException:CQL类型varchar的值0的类型无效,需要类java.lang.String,但类java。lang.Long提供了
。问题是,我试图将键绑定到第一个参数,而不是最后一个。这是一个字符串,不是长字符串
我可以通过给分区参数一个名称来解决这个问题,但我必须通过方法参数来获取名称,或者通过指定它的索引来解决,这将再次需要一个额外的方法参数。无论哪种方式,如果我使用名称或索引,我必须将其与特定类型绑定。例如:bs.setLong(“,partitionKey”);
。由于某些原因,我不能让BoundStatement来解释最后一个参数的类型
我希望避免显式地传递参数名而忽略类型问题。有什么可以做的吗
谢谢!我在“Apache Cassandra用户邮件列表的DataStax Java驱动程序”中发布了相同的问题,并表示我缺少的功能可能会添加到DataStax Java驱动程序的下一个版本(2.2)中 在JAVA-721(将在2.2中介绍)中,我们暂时计划 将以下带有签名的方法添加到BoundStatement: public BoundStatement setObject(inti,V)public BoundStatement setObject(字符串名称,V) 及 您可以在2.1中模拟setObject:
void setObject(BoundStatement bs, int position, Object object,
ProtocolVersion protocolVersion) {
DataType type = bs.preparedStatement().getVariables().getType(position);
ByteBuffer buffer = type.serialize(object, protocolVersion);
bs.setBytesUnsafe(position, buffer);
}
为了避免传递参数名,可以做的一件事是查看
对于尚未绑定的位置:
int findUnsetPosition(BoundStatement bs) {
int size = bs.preparedStatement().getVariables().size();
for (int i = 0; i < size; i++)
if (!bs.isSet(i))
return i;
throw new IllegalArgumentException("found no unset position");
}
int findUnsetPosition(bounds语句){
int size=bs.preparedStatement().getVariables().size();
对于(int i=0;i
但我不推荐它,因为如果
用户忘记绑定一个非PK变量
我的方法是要求用户传递一个回调,该回调设置
主键:
interface PKBinder<T> {
void bind(BoundStatement bs, T pk);
}
public <T> Future<List<ResultSet>> executeMultipleAsync(final BoundStatement statement, PKBinder<T> pkBinder, final T...
接口绑定器{
无效绑定(bounds,T pk);
}
公共未来执行器MultipleXync(最终边界语句,PKBinder PKBinder,最终T。。。
分区键)
作为奖励,这也可以用于复合分区键