For a Detailed Study on JCR Queries Please see this article.
JCR SQL 2 FULL Tutorial: CHEAT SHEET
Java content repository, better known as JCR is a modern approach to our database solutions.
While working on JCR I found many rather simple techniques to write JCR queries from our JAVA application.
Some of them have been described below to help fellow developers.
For this example, we will try to fetch all the "employee" nodes under the "codermagnet" parent node.
Download the Jack Rabbit Jar File form
http://www.apache.org/dyn/closer.cgi/jackrabbit/2.8.1/jackrabbit-standalone-2.8.1.jar
and place the Jack Rabbit jar in the build path of your project.
OPTION 1: Querying JCR using QueryManager API
Create a new class file as shown below.
File: JCRQueryExample.java
package net.codermag.jcr.test;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Repository;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.jackrabbit.core.TransientRepository;
public class JCRQueryExample {
public static void main(String[] args) throws Exception {
// Create a Session
Repository repository = new TransientRepository();
repository = JcrUtils.getRepository("http://localhost:4502/crx/server");
Session session = repository.login(new SimpleCredentials("admin","admin".toCharArray()));
//Building and Executing the Query
QueryManager queryManager = session.getWorkspace().getQueryManager();
String sqlStatement = "SELECT * FROM [nt:base] AS s WHERE ISDESCENDANTNODE([/content/codermagnet/employees])";
Query query = queryManager.createQuery(sqlStatement, "JCR-SQL2");
QueryResult result = query.execute();
//Doing Something with the nodes returned.. Printing the paths
NodeIterator iterator = result.getNodes();
while (iterator.hasNext()) {
System.out.println(((Node) iterator.next()).getPath());
}
}
}
Output:
/content/codermagnet/employees/kuper
/content/codermagnet/employees/john
/content/codermagnet/employees/harry
/content/codermagnet/employees/smith
OPTION 2: Quering JCR using ResourceResolver.findResources() method.
Another very handy and short way of doing this is illustrated below. This is my favorite as its a one-liner query and is cute, clean, and fast. One point that we need to remember while doing this is that for this second option we need the implicit "ResourceResolver" object. So this is more appropriate to be used as some sort of sling service inside our JCR application.
File: JCRQueryExample2.java
package net.codermag.jcr.test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.jcr.Node;
import javax.jcr.query.Query;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
public class JCRQueryExample2 {
public List<Node> getNodes(SlingHttpServletRequest request)
throws Exception {
List<Node> nodes = new ArrayList<Node>();
ResourceResolver resolver = request.getResourceResolver();
// Executing query in One Line....!!!!
Iterator<Resource> nodeIter = resolver
.findResources("SELECT * FROM [nt:base] AS s WHERE ISDESCENDANTNODE([/content/codermagnet/employees])",
Query.JCR_SQL2);
// Converting the Resource object to Node and then storing as arraylist
while (nodeIter.hasNext()) {
nodes.add(nodeIter.next().adaptTo(Node.class));
}
return nodes;
}
}
Option 3: Quering JCR using QueryBuilder API
File:JCRQueryExample3.java
Note: For testing the below XPATH query beforehand you can use the QueryBuilder debugger console at this URL
http://localhost:4502/libs/cq/search/content/querydebug.html
package com.realogy.sir.core.servlets;
import java.util.HashMap;
import java.util.Map;
import javax.jcr.Session;
import org.apache.sling.api.SlingHttpServletRequest;
import com.day.cq.search.PredicateGroup;
import com.day.cq.search.Query;
import com.day.cq.search.QueryBuilder;
import com.day.cq.search.result.Hit;
import com.day.cq.search.result.SearchResult;
public class JCRQueryExample3 {
public void getNodes(SlingHttpServletRequest request)throws Exception {
//Form the map and fill all the required parameters in the map
Map<String,String> map = new HashMap<String,String>();
map.put("path", "/content/codermagnet/employees");
map.put("type", "nt:base");
map.put("orderby","@name");
//Quering JCR using com.day.cq.search.QueryBuilder API
PredicateGroup predicateGroup = PredicateGroup.create(map);
QueryBuilder builder = request.getResourceResolver().adaptTo(QueryBuilder.class);
Query query = builder.createQuery(predicateGroup, request.getResourceResolver().adaptTo(Session.class));
SearchResult result = query.getResult();
//Do something with the results
for (Hit hit : result.getHits()) {
String path = hit.getPath();
System.out.println(path);
}
}
}
Output:
/content/codermagnet/employees/harry
/content/codermagnet/employees/john
/content/codermagnet/employees/kuper
/content/codermagnet/employees/smith
You can use Option 2 and Option 3 when writing servlets or inside scriptlet tags in AEM JSP pages where you have access or can derive the "resourceResolver" implicit object. In the above option, I have derived the "resourceResolver" object from the org.apache.sling.api.SlingHttpServletRequest that is passed to the method.
No comments:
Post a Comment
If you have any doubts or questions, please let us know.