2016-03-17 4 views
1

Я использую PreparedStatement и BoundStatement для выполнения некоторых запросов Cassandra. Проблема в том, что я пытаюсь использовать для них ограничение. Это то, что у меня есть:Cassandra BoundStatement с ограничением

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()) 
     ); 

Всякий раз, когда мне нужно, чтобы выполнить запрос, я называю эту функцию:

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; 
} 

Однако, это работает только без оговорки предела в первом фрагменте кода. Я не знаю, как указать лимит во втором фрагменте. Я не хочу использовать строку, что-то вроде

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

Есть ли способ сделать это с помощью BoundStatement? Я не вижу ничего подобного BoundStatement.limit() или setLimit().

Спасибо, Serban

ответ

4

Самый простой способ заключается в использовании именованного маркер предела:

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)); 

Вы также можете сохранить анонимные маркеры и использовать позиционные сеттеры:

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

Для записи, когда вы используете анонимные маркеры, Cassandra называет их автоматически. Для столбцов это имена столбцов (ваш пример основан на этом), а для лимита это [limit]. Так что это также будет работать:

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

Если вы сомневаетесь, вы можете проверить метаданные подготовленное заявление, чтобы увидеть, что он ожидает:

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

Лично мне нравится именованные маркеры для ясности, но YMMV.

+0

Удивительный! Благодаря! –

Смежные вопросы