问题
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