我试图编写一个通用工具,用于将Cassandra表内容从一个密钥空间复制到另一个密钥空间(可能在不同的集群中)。所有的表都不算太大。
以下是我的工作:
Session source = ...
Session destination = ...
TableMetadata table = ...
final ResultSet rs = source.execute("select * from " + table.getName());
String insertCql = ...
PreparedStatement preparedStatement = destination.prepare(insertCql);
for (Row row : rs) {
final BoundStatement boundStatement = preparedStatement.bind();
for (int i = 0; i < rs.getColumnDefinitions().size(); i++) {
// bind column value from row to bountStatement
}
session.execute(boundStatement);
}
问题是如何将列值从row
复制到boundStatement
。我可以使用row.getObject(i)
阅读,但setObject()
中没有相应的BoundStatement
。
更准确地说,此方法存在于驱动程序的2.2版(它的cassandra-driver-dse
)中,但该版本不适用于Cassandra 3,而且版本3不适用于驱动程序({{1} })cassandra-driver-core
方法不存在。相反,有大量setObject()
方法,所有这些方法都需要set()
,Class
或TypeToken
。
我在哪里可以获得这些? TypeCodec
只给了我ColumnDefinition
。使用DataType
获取row.getObject(i).getClass()
。
也许有更好的方法来完成这项任务(模式无关的复制)?
我可以查看Class
如果列和每个类型的情况使用DataType
等等,但这看起来有点过于复杂和脆弱。
答案 0 :(得分:3)
您需要在insert语句中使用绑定变量,然后将预准备语句与结果中的列值绑定。有点像:
String insertCql = "INSERT INTO ks.tb (...) values (?,?,...)";
for (Row row : rs) {
List bindVariables = new ArrayList();
for (int i = 0; i < rs.getColumnDefinitions().size(); i++) {
bindVariables.add(rs.getObject(i));
}
final BoundStatement boundStatement = preparedStatement.bind(bindVariables.toArray(new Object[0]));
session.execute(boundStatement);
}