如何使用 datastax java 驱动程序以通用方式将值绑定到绑定语句?

How to bind values to bound statement in a generic way using datastax java driver?

我正在使用 Datastax Java 驱动程序在 Cassandra 中读取和写入数据。我使用的是 datastax java 驱动程序 3.1.0,我的 cassandra 集群版本是 2.0.10.

我创建了以下两种方法来执行我的 cql 查询。

当我不需要在我的 cql 查询中设置任何值时,我正在调用第一个方法,因此它适用于如下所示的 cql 字符串:

select * from testkeyspace.testtable where row_id=1 // cql-1
select * from testkeyspace.meta where row_id=1 // cql-2
select * from testkeyspace.proc where row_id=1 // cql-3

现在,每当我有这样的查询时,我都需要调用第二种方法:

select * from testkeyspace.testtabletwo where row_id=1 and active=? // cql-4
select * from testkeyspace.storage where topic=? and parts=? // cql-5, in this part is Integer and topic is String.

所以我的问题是如何让我的第二种方法更通用,这样如果我需要使用 BoundStatement 在我的 cql 查询中设置 n 个值,它应该可以工作吗?现在我不确定在使用传递给该方法的值调用我的第二个方法时我应该为 cql-4cql-5 做什么?我知道我必须使用 BoundStatement 设置这些值,但如果我需要设置两个或三个或四个值,我如何才能使该方法通用,这样我就不需要硬编码任何东西?有些可以是整数,有些可以是字符串。

第一种方法:-

  public ResultSet executeQuery(final String cql) {
    return executeWithSession(new SessionCallable<ResultSet>() {
      @Override
      public ResultSet executeWithSession(Session session) {
        BoundStatement bs = getStatement(cql);
        bs.setConsistencyLevel(consistencyLevel);
        return session.execute(bs);
      }
    });
  }

第二种方法:-

  public ResultSet executeQuery(final String cql, final Object... values) {
    return executeWithSession(new SessionCallable<ResultSet>() {
      @Override
      public ResultSet executeWithSession(Session session) {
        BoundStatement bs = getStatement(cql);
        bs.setConsistencyLevel(consistencyLevel);
        // how to set these **values** into my cql query using BoundStatement in a generic way 
        // so that I don't need to hardcode anything for cql-4 and cql-5
        return session.execute(cql, values);
      }
    });
  }

  // cache the prepared statement
  private BoundStatement getStatement(final String cql) {
    Session session = getSession();
    PreparedStatement ps = cache.get(cql);
    // no statement cached, create one and cache it now.
    if (ps == null) {
      ps = session.prepare(cql);
      PreparedStatement old = cache.putIfAbsent(cql, ps);
      if (old != null)
        ps = old;
    }
    return ps.bind();
  }

我必须在这里使用 BoundStatement 吗?我想我必须这样做,因为这是我设置一致性级别的方式?

怎么样:

public ResultSet executeQuery(final String cql, final Object... values) {
    return executeWithSession(new SessionCallable<ResultSet>() {
        @Override
        public ResultSet executeWithSession(Session session) {
            BoundStatement bs = getStatement(cql, values);
            bs.setConsistencyLevel(consistencyLevel);
            return session.execute(cql);
        }
    });
}

// cache the prepared statement
private BoundStatement getStatement(final String cql, Object... values) {
    Session session = getSession();
    PreparedStatement ps = cache.get(cql);
    // no statement cached, create one and cache it now.
    if (ps == null) {
        ps = session.prepare(cql);
        PreparedStatement old = cache.putIfAbsent(cql, ps);
        if (old != null)
            ps = old;
    }
    return ps.bind(values);
}