Usage & Samples

People already familiar with Hibernate's Criteria will find almost no difference (type names and methods have been kept the same on purpose, whenever possible): you create a Criteria object with the createCriteria static method in JCRCriteriaFactory.
After that you can play with it by setting:

  • the repository you are querying
  • the base path where the query should operate
  • any combination of Restrictions
  • one or more Orders
  • pagination, simply calling setPaging giving the number of items per page and the number of the page you want to retrieve

Then you call the execute() method to get your result. The object returned is an implementation of AdvancedResult, an object that exposes: 

  • the total number of results
  • pagination info (number of current page, number of available pages, items per page)
  • spell checked suggestions (if you configured a spell checker for the jackrabbit search index)
  • the list of result, actually an iterator of  AdvancedResultItem objects, which are no more than Content with the addition of a couple of methods to get excerpts and scores.

See the following example:

        Calendar begin = Calendar.getInstance();
        begin.set(2004, Calendar.JANUARY, 1);
        Calendar end = Calendar.getInstance();
        end.set(2008, Calendar.DECEMBER, 1);

        AdvancedResult result = JCRCriteriaFactory.createCriteria()
            .setWorkspace("website")
            .setBasePath("/dogs")
            .add(Restrictions.eq(Criterion.JCR_PRIMARYTYPE, "mgnl:content"))
            .add(Restrictions.contains("@name", "Nana"))
            .add(Restrictions.gt("@weight", Float.valueOf(10)))
            .add(Restrictions.between("@birthDate", begin, end))
            .addOrder(Order.desc("@name"))
            .execute();

This will be translated into the following xpath statement:

//dogs//*[((jcr:contains(@name, 'Nana')) and (@weight>10.0) 
   and (@birthDate >=xs:dateTime('2004-01-01T00:00:00.000+00:00')
   and @birthDate <=xs:dateTime('2008-12-01T23:59:59.000+00:00')))]
   order by @name descending 

You can then obtain an iterator on result items by calling getItems(). By default you will get AdvancedResultItem objects, which are simply a specialized version of Content and can be used as is as you would do with Magnolia content objects. You can also specify  a different type to be returned, e.g.

ResultIterator<Pet> pets = result.getItems(Pet.class);

Internally, this will use info.magnolia.content2bean.Content2BeanUtil.toBean() to transform nodes into beans.

So, for example, if you have a domain Pet class like this

public class Pet
{
 private String name;
 private Float weight;
 private Calendar birthDate;
 //getters and setters here...
}

Content nodes returned by the above query will be automatically converted to and populate instances of the Pet type.

Pagination

Pagination support is built-in in Criteria queries. Assuming you want to get the full list of pets from the previous example, in pages with 10 items each, you can simply use the setPaging() call:

        AdvancedResult result = JCRCriteriaFactory.createCriteria() //
            .setWorkspace("website")
            .setBasePath("/dogs")
            .add(Restrictions.eq(Criterion.JCR_PRIMARYTYPE, "mgnl:content"))
            .addOrder(Order.desc("@name"))
            .setPaging(10, 1)
            .execute();
        
        result.getTotalSize(); // this is the full number of dogs
        result.getPage(); // the current page
        result.getNumberOfPages(); // the number of pages
        result.getItems(); // the items in the current page

Project info & quick links