В Hibernate существует интуитивный и наращиваемый API для критериальных запросов. Сейчас данный API уступает в мощности более зрелым возможностям HQL запросов. В частности, критериальные запросы не поддерживают проекции (projection) и агрегации.
Интерфейс net.sf.hibernate.Criteria представляет запрос по заданному персистентному классу. Фабрикой для создания экземляров Criteria является Session.
Criteria crit = sess.createCriteria(Cat.class); crit.setMaxResults(50); List cats = crit.list();
Индивидуальным критерионом (criterion) является экземпляр интерфейса net.sf.hibernate.expression.Criterion. Класс net.sf.hibernate.expression.Expression определяющий фабричные методы для получения определенных встроеных типов Criterion.
List cats = sess.createCriteria(Cat.class) .add( Expression.like("name", "Fritz%") ) .add( Expression.between("weight", minWeight, maxWeight) ) .list();
Выражения (expressions) могут быть логически сгрупированны
List cats = sess.createCriteria(Cat.class) .add( Expression.like("name", "Fritz%") ) .add( Expression.or( Expression.eq( "age", new Integer(0) ), Expression.isNull("age") ) ) .list();
List cats = sess.createCriteria(Cat.class) .add( Expression.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) ) .add( Expression.disjunction() .add( Expression.isNull("age") ) .add( Expression.eq("age", new Integer(0) ) ) .add( Expression.eq("age", new Integer(1) ) ) .add( Expression.eq("age", new Integer(2) ) ) ) ) .list();
Существует множество типов критерионов (criterion) (подклассы Expression), но с помощью одного из них возможно задавать SQL напрямую.
List cats = sess.createCriteria(Cat.class) .add( Expression.sql("lower({alias}.name) like lower(?)", "Fritz%", Hibernate.STRING) ) .list();
Вместо {alias} будет подставлено значение синонима запрашиваемой сущности.
Вы можете отсортировать результаты при помощи net.sf.hibernate.expression.Order
List cats = sess.createCriteria(Cat.class) .add( Expression.like("name", "F%") .addOrder( Order.asc("name") ) .addOrder( Order.desc("age") ) .setMaxResults(50) .list();
Вы можете легко специфицировать ограничения для связанных сущюностей используя createCriteria() для навигации по ассоциациям.
List cats = sess.createCriteria(Cat.class) .add( Expression.like("name", "F%") .createCriteria("kittens") .add( Expression.like("name", "F%") .list();
Учтите, что второй вызов createCriteria() вернет новый экземляр Criteria, который будет укзывать на элемент коллекции kittens.
В определенных случаях используется альтернативная форма (см. ниже).
List cats = sess.createCriteria(Cat.class) .createAlias("kittens", "kt") .createAlias("mate", "mt") .add( Expression.eqProperty("kt.name", "mt.name") ) .list();
(createAlias() не создает нового экземпляра Criteria.)
Учтите, что коллекция kittens содержится в экземплярах объекта Cat возвращаемая предыдущими двумя запросами не фильтруется критериями! Если вам нужно получить только те элементы kittens которые соответсвуют критерию, вы должны использовать returnMaps().
List cats = sess.createCriteria(Cat.class) .createCriteria("kittens", "kt") .add( Expression.eq("name", "F%") ) .returnMaps() .list(); Iterator iter = cats.iterator(); while ( iter.hasNext() ) { Map map = (Map) iter.next(); Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS); Cat kitten = (Cat) map.get("kt"); }
Вы можете специфицировать семантику выборки данных по ассоциациям во время испольнения используя setFetchMode().
List cats = sess.createCriteria(Cat.class) .add( Expression.like("name", "Fritz%") ) .setFetchMode("mate", FetchMode.EAGER) .setFetchMode("kittens", FetchMode.EAGER) .list();
Этот запрос будет получать mate и kittens используя outer join.
Класс net.sf.hibernate.expression.Example позволяет вам конструировать критерионы (criterion) запросов из данных заданного экземпляра класса.
Cat cat = new Cat(); cat.setSex('F'); cat.setColor(Color.BLACK); List results = session.createCriteria(Cat.class) .add( Example.create(cat) ) .list();
Свойства версии, идентифицаторы и ассоциации игнорируются. По умолчанию, параметры содержащие null значения так же исключаются из сконструированного запроса.
Вы можете настраивать правила работы Example.
Example example = Example.create(cat) .excludeZeroes() //исключает свойства с нулевыми значениями .excludeProperty("color") //исключает своство "color" .ignoreCase() //задает независимое от регистра сравнение строк .enableLike(); //использует like для сравнения строк List results = session.createCriteria(Cat.class) .add(example) .list();
Вы можете так же использовать примеры для задания критериев ассоциированных объектов.
List results = session.createCriteria(Cat.class) .add( Example.create(cat) ) .createCriteria("mate") .add( Example.create( cat.getMate() ) ) .list();