第 2 章 创建 Ickle 查询
Data Grid 提供了一个 Ickle 查询语言,可让您创建关系和全文本查询。
2.1. Ickle queries
要使用 API,首先获取 QueryFactory 到缓存,然后调用 .create ()
方法,传递要在查询中使用的字符串。每个 QueryFactory
实例都绑定到与 Search
相同的 缓存
实例,但它是一个无状态和线程安全对象,可用于并行创建多个查询。
例如:
// Remote Query, using protobuf QueryFactory qf = org.infinispan.client.hotrod.Search.getQueryFactory(remoteCache); Query<Transaction> q = qf.create("from sample_bank_account.Transaction where amount > 20"); // Embedded Query using Java Objects QueryFactory qf = org.infinispan.query.Search.getQueryFactory(cache); Query<Transaction> q = qf.create("from org.infinispan.sample.Book where price > 20"); // Execute the query QueryResult<Book> queryResult = q.execute();
查询始终以单个实体类型为目标,并评估单个缓存的内容。不支持对多个缓存运行查询或创建以多种实体类型(加入)为目标的查询。
执行查询并获取结果非常简单,就像调用 Query
对象的 execute ()
方法一样。执行后,在同一实例上调用 execute ()
将重新执行查询。
2.1.1. 分页
您可以使用 Query.maxResults (int maxResults)
来限制返回的结果数量。这可以与 Query.startOffset (long startOffset)
一起使用,以实现结果集的分页。
// sorted by year and match all books that have "clustering" in their title // and return the third page of 10 results Query<Book> query = queryFactory.create("FROM org.infinispan.sample.Book WHERE title like '%clustering%' ORDER BY year").startOffset(20).maxResults(10)
2.1.2. 命中数
QueryResult
对象具有 .hitCount ()
方法,可返回查询结果总数,而不考虑任何分页参数。因性能原因,点击数仅适用于索引查询。
2.1.3. iteration
Query
对象具有 .iterator ()
方法,用于获取结果 lazily。它返回一个 CloseableIterator
实例,实例必须在使用量后关闭。
当前限制了对 Remote Queries 的迭代支持,因为它将在迭代前首先向客户端获取所有条目。
2.1.4. 命名的查询参数
也可以为每个执行构建新的 Query 对象,而是在查询中包含命名的参数,可在执行前替换为实际值。这允许定义一次查询,并多次高效地执行查询。参数只能在 Operator 右侧使用,并在通过提供由 org.infinispan.query.dsl.Expression.param (String paramName)
方法生成的对象创建时定义。定义了参数后,可以通过调用 Query.setParameter (parameterName, value)
或 Query.setParameters (parameterMap)
来设置这些参数,如下例所示。
QueryFactory queryFactory = Search.getQueryFactory(cache); // Defining a query to search for various authors and publication years Query<Book> query = queryFactory.create("SELECT title FROM org.infinispan.sample.Book WHERE author = :authorName AND publicationYear = :publicationYear").build(); // Set actual parameter values query.setParameter("authorName", "Doe"); query.setParameter("publicationYear", 2010); // Execute the query List<Book> found = query.execute().list();
或者,您可以提供一个实际参数值映射来一次性设置多个参数:
一次性设置多个命名参数
Map<String, Object> parameterMap = new HashMap<>(); parameterMap.put("authorName", "Doe"); parameterMap.put("publicationYear", 2010); query.setParameters(parameterMap);
查询解析、验证和执行规划工作的一个主要部分是在首次执行带有参数的查询过程中执行的。与使用恒定值而非查询参数相比类似的查询相比,这个工作不会在后续执行过程中重复。
2.1.5. 查询执行
Query
API 提供了在缓存上执行 Ickle 查询的方法:
-
query.execute ()
运行 SELECT 语句并返回结果。 -
query.executeStatement ()
运行 DELETE 语句并修改数据。
您应该始终调用 executeStatement ()
来修改数据并调用 execute ()
来获取查询的结果。