diff --git a/README.md b/README.md index 11df5b9..d8fa4fd 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,16 @@ This example should show how the `scan_consistency` parameter may be enabled for Go | node.js +### Query - Better reuse of queries with adhoc(false) and Prepared Statements +This example should demonstrate best practice when a statement is to be reused heavily. Setting the `adhoc` N1QL query tuning to `false` will use Prepared Statements in the background, which is useful in such a case. Note how this works with placeholders (but of course simple statements work too). + +C | +Python | +[Java](java/src/main/java/com/couchbase/devguide/QueryPrepared.java) | +.NET | +Go | +node.js + ### CAS Handling - Using CAS for concurrent mutations This example will demonstrate concurrent mutations with and without using the CAS value. Without using the CAS value, some modifications may end up getting diff --git a/java/src/main/java/com/couchbase/devguide/QueryPrepared.java b/java/src/main/java/com/couchbase/devguide/QueryPrepared.java new file mode 100644 index 0000000..2176ec6 --- /dev/null +++ b/java/src/main/java/com/couchbase/devguide/QueryPrepared.java @@ -0,0 +1,64 @@ +package com.couchbase.devguide; + +import com.couchbase.client.java.document.json.JsonObject; +import com.couchbase.client.java.query.N1qlParams; +import com.couchbase.client.java.query.N1qlQuery; +import com.couchbase.client.java.query.N1qlQueryResult; +import com.couchbase.client.java.query.N1qlQueryRow; +import com.couchbase.client.java.query.ParameterizedN1qlQuery; + +/** + * Example of Querying with N1QL and its Prepared Statement feature, in Java for the Couchbase Developer Guide. + */ +public class QueryPrepared extends ConnectionBase { + + private static final String PLACEHOLDER_STATEMENT = "SELECT airportname FROM `travel-sample` WHERE city=$city AND type=\"airport\""; + + private N1qlQueryResult queryCity(String city, boolean optimize) { + //the placeholder values can be provided as a JSON array (if using $1 syntax) + // or map-like JSON object (if using $name syntax) + JsonObject placeholderValues = JsonObject.create().put("city", city); + + //the N1qlParams.adhoc(false) is used to trigger server-side optimizations, namely preparing + // the query and reusing the prepared data on subsequent calls + N1qlParams params = N1qlParams.build().adhoc(!optimize); + + ParameterizedN1qlQuery query = N1qlQuery.parameterized(PLACEHOLDER_STATEMENT, placeholderValues, params); + return bucket.query(query); + } + + @Override + protected void doWork() { + LOGGER.info("Airports in Reno: "); + N1qlQueryResult result = queryCity("Reno", true); + for (N1qlQueryRow row : result) { + LOGGER.info("\t" + row); + } + LOGGER.info("1st query took " + result.info().executionTime()); + + result = queryCity("Dallas", true); + LOGGER.info("\nAirports in Dallas: "); + for (N1qlQueryRow row : result) { + LOGGER.info("\t" + row); + } + LOGGER.info("2nd query took " + result.info().executionTime()); + + LOGGER.info("\nAirports in Los Angeles: "); + result = queryCity("Los Angeles", true); + for (N1qlQueryRow row : result) { + LOGGER.info("\t" + row); + } + LOGGER.info("3rd query took " + result.info().executionTime()); + + LOGGER.info("\nCompare with unprepared (adhoc) query for Los Angeles: "); + LOGGER.info(queryCity("Los Angeles", false).info().executionTime()); + + //invalidateQueryCache empties the local cache of optimized statements, returning the previous count + //of such statements. + LOGGER.info("\nThe SDK prepared " + bucket.invalidateQueryCache() + " queries"); + } + + public static void main(String[] args) { + new QueryPrepared().execute(); + } +}