Cassandra BoundStatement with limit

不想你离开。 提交于 2019-12-23 18:16:48

问题


I am using PreparedStatement and BoundStatement to execute some Cassandra queries. The problem is, I am trying to use a limit on these. This is what I have:

 selectByDatasetIdAndTimePreparedStatement = getSession().prepare(
                QueryBuilder.select()
                        .all()
                        .from(KEYSPACE_NAME, TABLE_NAME)
                        .where(QueryBuilder.eq(AFFILIATION_ID_COLUMN, QueryBuilder.bindMarker()))
                        .and(QueryBuilder.eq(DATASET_ID_COLUMN, QueryBuilder.bindMarker()))
                        .and(QueryBuilder.lte(TIME_COLUMN, QueryBuilder.bindMarker()))
                        //.limit(QueryBuilder.bindMarker())
        );

Whenever I need to run the query, i call this function:

public Statement buildSelectByDatsetIdAndTimePreparedStatment(String affiliationId, String datasetId, Long time, int limit)
{
    BoundStatement boundStatement = selectByDatasetIdAndTimePreparedStatement
            .bind()
            .setString(AFFILIATION_ID_COLUMN, affiliationId)
            .setString(DATASET_ID_COLUMN, datasetId)
            .setLong(TIME_COLUMN, time);
    databaseManager.applyReadStatementsConfiguration(boundStatement);
    return boundStatement;
}

However, this works only without the limit clause in the first code snippet. I don't know how to specify the limit in the second snippet. I don't want to use string, something like

databaseManager.getSession().execute("SELECT * FROM myTable where ... limit 10);

Is there any way to do this using BoundStatement? I don't see anything like BoundStatement.limit() or setLimit().

Thanks, Serban


回答1:


The easiest way is to use a named marker for the limit:

PreparedStatement pst = session.prepare(
        select().all()
                .from("foo")
                .where(eq("k", bindMarker()))
                .limit(bindMarker("l")));     // here

session.execute(pst.bind()
        .setInt("k", 1)
        .setInt("l", 10));

You could also keep the anonymous markers and use positional setters:

                .where(eq("k", bindMarker()))
                .limit(bindMarker())); // no name
session.execute(pst.bind()
        .setInt(0, 1)
        .setInt(1, 10));

For the record, when you use anonymous markers, Cassandra names them automatically. For columns these are the column names (your example relies on that), and for the limit it turns out to be [limit]. So this would also work:

                .where(eq("k", bindMarker()))
                .limit(bindMarker())); // no name
session.execute(pst.bind()
        .setInt("k", 1)
        .setInt("[limit]", 10));

When in doubt, you can inspect the prepared statement's metadata to see what it expects:

for (ColumnDefinitions.Definition v : pst.getVariables()) {
    System.out.printf("%s %s%n", v.getName(), v.getType().getName());
}

Personally I like named markers for clarity, but YMMV.



来源:https://stackoverflow.com/questions/36061457/cassandra-boundstatement-with-limit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!