如何从Request提取CQL查询?解决Cassandra驱动类型转换异常
从Cassandra Request中提取CQL查询的解决方案
你遇到的ClassCastException是因为驱动内部用动态代理包装了Request实例,直接强转成SimpleStatement会失败。以下是可行的提取方法:
1. 区分Request的实际类型
Request是驱动中所有请求的顶层接口,实际可能是SimpleStatement、BoundStatement、BatchStatement等不同实现,需要针对性处理:
- SimpleStatement:直接调用
getQuery()获取原始CQL - BoundStatement:预编译语句的绑定实例,需从关联的
PreparedStatement中提取CQL - BatchStatement:遍历批量中的子语句,逐个提取后拼接(或按需处理)
2. 代码实现示例
import com.datastax.oss.driver.api.core.cql.BatchStatement; import com.datastax.oss.driver.api.core.cql.BoundStatement; import com.datastax.oss.driver.api.core.cql.SimpleStatement; import com.datastax.oss.driver.api.core.cql.Statement; import com.datastax.oss.driver.api.core.session.Request; public String extractCqlFromRequest(Request request) { if (request instanceof SimpleStatement simpleStatement) { return simpleStatement.getQuery(); } else if (request instanceof BoundStatement boundStatement) { // BoundStatement本身不存储原始CQL,需从PreparedStatement获取 return boundStatement.getPreparedStatement().getQuery(); } else if (request instanceof BatchStatement batchStatement) { // 处理批量语句,这里简单拼接所有子语句的CQL StringBuilder cqlBuilder = new StringBuilder("BEGIN BATCH\n"); for (Statement<?> subStatement : batchStatement.getStatements()) { // 递归调用提取子语句的CQL cqlBuilder.append(extractCqlFromRequest(subStatement)).append(";\n"); } cqlBuilder.append("APPLY BATCH;"); return cqlBuilder.toString(); } else { // 处理其他未知类型的Request throw new UnsupportedOperationException("Unsupported Request type: " + request.getClass().getName()); } }
3. 处理动态代理的情况
如果Request是代理类,可尝试用unwrap()方法获取真实实例(驱动支持的话):
if (request.getClass().getMethod("unwrap", Class.class) != null) { Request actualRequest = (Request) request.getClass().getMethod("unwrap", Class.class).invoke(request, Request.class); return extractCqlFromRequest(actualRequest); }
内容的提问来源于stack exchange,提问作者enthusiast
相关产品推荐
相关产品推荐

