2016-03-17 2 views
1

J'utilise PreparedStatement et BoundStatement pour exécuter certaines requêtes Cassandra. Le problème est, j'essaie d'utiliser une limite sur ceux-ci. Voilà ce que j'ai:Cassandra BoundStatement avec limite

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

Chaque fois que je dois exécuter la requête, j'appelle cette fonction:

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

Cependant, cela ne fonctionne que sans la clause limite dans le premier extrait de code. Je ne sais pas comment spécifier la limite dans le deuxième extrait. Je ne veux pas utiliser de chaîne, quelque chose comme

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

Y at-il un moyen de le faire en utilisant BoundStatement? Je ne vois rien comme BoundStatement.limit() ou setLimit().

Merci, Serban

Répondre

4

La façon la plus simple est d'utiliser un marqueur du nom de la limite:

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

Vous pouvez également conserver les marqueurs anonymes et utiliser setters de position:

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

Pour mémoire, lorsque vous utilisez des marqueurs anonymes, Cassandra les nomme automatiquement. Pour les colonnes, ce sont les noms des colonnes (votre exemple s'appuie sur cela), et pour la limite il s'avère être [limit]. Donc, ce serait aussi travailler:

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

En cas de doute, vous pouvez vérifier les métadonnées de déclaration préparée pour voir ce qu'il attend:

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

Personnellement, j'aime des marqueurs nommés pour plus de clarté, mais YMMV.

+0

Génial! Merci! –