在阅读了datastax博客中的“Asynchronous queries with the Java driver”文章之后,我试图实现一个类似于“案例研究:多分区查询,又名客户端SELECT”一节中的解决方案。 ..IN“”。
我目前的代码看起来像这样:
|
但是,我想改进这一点。在这个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);
}
我希望这个方法的客户端给我一个带有已绑定参数的BoundStatement(在这种情况下是两个参数)和一个分区键列表。在这种情况下,我需要做的就是绑定分区键并执行查询。不幸的是,当我将密钥绑定到此语句时,我失败并出现错误 - SELECT * FROM <column_family_name> WHERE <param1> = :p1_name AND param2 = :p2_name AND <partiotion_key_name> = ?;
。问题是,我尝试将密钥绑定到第一个参数而不是最后一个参数。这是一个字符串而不是很长。
我可以通过给分区参数一个名称来解决这个问题,但是我必须通过方法参数获取名称,或者通过指定它的索引再次需要一个额外的方法参数。无论哪种方式,如果我使用名称或索引,我必须将其与特定类型绑定。例如:com.datastax.driver.core.exceptions.InvalidTypeException: Invalid type for value 0 of CQL type varchar, expecting class java.lang.String but class java.lang.Long provided
。出于某种原因,我不能将它留给BoundStatement来解释最后一个参数的类型。
我想避免显式传递参数名称并绕过类型问题。有什么可以做的吗?
谢谢!
答案 0 :(得分:3)
我在'用于Apache Cassandra用户邮件列表的DataStax Java驱动程序'和got an answer中发布了相同的问题,说我可能会在数据传输java的下一个版本(2.2)中添加我缺少的功能驱动程序。
在JAVA-721(将在2.2中介绍)中,我们暂时计划进行 将以下带签名的方法添加到BoundStatement:
public BoundStatement setObject(int i,v v)public BoundStatement setObject(String name,V 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"); }
我不推荐它,因为如果它是丑陋和不可预测的 用户忘了绑定其中一个非PK变量。
我这样做的方法是要求用户传递设置的回调 PK:
interface PKBinder<T> { void bind(BoundStatement bs, T pk); } public <T> Future<List<ResultSet>> executeMultipleAsync(final BoundStatement statement, PKBinder<T> pkBinder, final T...
partitionKeys)
作为奖励,这也适用于复合分区键。