Acompaña a Hibernate una API de consultas por criterios intuitiva y extensible.
La interface
org.hibernate.Criteria
representa una consulta contra una clase persistente en particular. LaSession
es una fábrica de instancias de Criteria
.Criteria crit = sess.createCriteria(Cat.class); crit.setMaxResults(50); List cats = crit.list();
Un criterio individual de consulta es una instancia de la interface
Restrictions can be grouped logically.
There are a range of built-in criterion types (
El sitio
You can also obtain a criterion from a
org.hibernate.criterion.Criterion
. La claseorg.hibernate.criterion.Restrictions
define métodos de fábrica para obtener ciertos tipos prefabricados deCriterion
.List cats = sess.createCriteria(Cat.class) .add( Restrictions.like("name", "Fritz%") ) .add( Restrictions.between("weight", minWeight, maxWeight) ) .list();
Restrictions can be grouped logically.
List cats = sess.createCriteria(Cat.class) .add( Restrictions.like("name", "Fritz%") ) .add( Restrictions.or( Restrictions.eq( "age", new Integer(0) ), Restrictions.isNull("age") ) ) .list();
List cats = sess.createCriteria(Cat.class) .add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) ) .add( Restrictions.disjunction() .add( Restrictions.isNull("age") ) .add( Restrictions.eq("age", new Integer(0) ) ) .add( Restrictions.eq("age", new Integer(1) ) ) .add( Restrictions.eq("age", new Integer(2) ) ) ) ) .list();
There are a range of built-in criterion types (
Restrictions
subclasses). One of the most useful allows you to specify SQL directly.List cats = sess.createCriteria(Cat.class) .add( Restrictions.sql("lower({alias}.name) like lower(?)", "Fritz%", Hibernate.STRING) ) .list();
El sitio
{alias}
será remplazado por el alias de fila de la entidad consultada.You can also obtain a criterion from a
Property
instance. You can create a Property
by callingProperty.forName()
:Property age = Property.forName("age"); List cats = sess.createCriteria(Cat.class) .add( Restrictions.disjunction() .add( age.isNull() ) .add( age.eq( new Integer(0) ) ) .add( age.eq( new Integer(1) ) ) .add( age.eq( new Integer(2) ) ) ) ) .add( Property.forName("name").in( new String[] { "Fritz", "Izi", "Pk" } ) ) .list();
You can order the results using
org.hibernate.criterion.Order
.List cats = sess.createCriteria(Cat.class) .add( Restrictions.like("name", "F%") .addOrder( Order.asc("name") ) .addOrder( Order.desc("age") ) .setMaxResults(50) .list();
List cats = sess.createCriteria(Cat.class) .add( Property.forName("name").like("F%") ) .addOrder( Property.forName("name").asc() ) .addOrder( Property.forName("age").desc() ) .setMaxResults(50) .list();
By navigating associations using
The second
There is also an alternate form that is useful in certain circumstances:
The kittens collections held by the
createCriteria()
you can specify constraints upon related entities:List cats = sess.createCriteria(Cat.class) .add( Restrictions.like("name", "F%") .createCriteria("kittens") .add( Restrictions.like("name", "F%") .list();
The second
createCriteria()
returns a new instance of Criteria
that refers to the elements of the kittens
collection.There is also an alternate form that is useful in certain circumstances:
List cats = sess.createCriteria(Cat.class) .createAlias("kittens", "kt") .createAlias("mate", "mt") .add( Restrictions.eqProperty("kt.name", "mt.name") ) .list();(
createAlias()
no crea una nueva instancia de Criteria
.)The kittens collections held by the
Cat
instances returned by the previous two queries are not pre-filtered by the criteria. If you want to retrieve just the kittens that match the criteria, you must use aResultTransformer
.List cats = sess.createCriteria(Cat.class) .createCriteria("kittens", "kt") .add( Restrictions.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"); }
You can specify association fetching semantics at runtime using
Esta consulta recuperará tanto
setFetchMode()
.List cats = sess.createCriteria(Cat.class) .add( Restrictions.like("name", "Fritz%") ) .setFetchMode("mate", FetchMode.EAGER) .setFetchMode("kittens", FetchMode.EAGER) .list();
Esta consulta recuperará tanto
mate
como kittens
por unión exterior (outer join). Ver Sección 19.1, “Estrategias de recuperación” para más información.
La clase
Las propiedades de versión, los identificadores y las asociaciones son ignorados. Por defecto, las propiedades valuadas a nulo son excluídas.
Puedes ajustar cómo se aplica el
Puedes incluso usar ejemplos para colocar criterios sobre objetos asociados.
org.hibernate.criterion.Example
te permite construir un criterio de consulta a partir de una instancia dada.Cat cat = new Cat(); cat.setSex('F'); cat.setColor(Color.BLACK); List results = session.createCriteria(Cat.class) .add( Example.create(cat) ) .list();
Las propiedades de versión, los identificadores y las asociaciones son ignorados. Por defecto, las propiedades valuadas a nulo son excluídas.
Puedes ajustar cómo se aplica el
Example
.Example example = Example.create(cat) .excludeZeroes() //exclude zero valued properties .excludeProperty("color") //exclude the property named "color" .ignoreCase() //perform case insensitive string comparisons .enableLike(); //use like for string comparisons List results = session.createCriteria(Cat.class) .add(example) .list();
Puedes incluso usar ejemplos para colocar criterios sobre objetos asociados.
List results = session.createCriteria(Cat.class) .add( Example.create(cat) ) .createCriteria("mate") .add( Example.create( cat.getMate() ) ) .list();
The class
No es necesario ningún "group by" explícito en una consulta por criterios. Ciertos tipos de proyecciones son definidos para ser proyecciones agrupadas, que además aparecen en la cláusula SQL
An alias can be assigned to a projection so that the projected value can be referred to in restrictions or orderings. Here are two different ways to do this:
Los métodos
Puedes también usar
org.hibernate.criterion.Projections
is a factory for Projection
instances. You can apply a projection to a query by calling setProjection()
.List results = session.createCriteria(Cat.class) .setProjection( Projections.rowCount() ) .add( Restrictions.eq("color", Color.BLACK) ) .list();
List results = session.createCriteria(Cat.class) .setProjection( Projections.projectionList() .add( Projections.rowCount() ) .add( Projections.avg("weight") ) .add( Projections.max("weight") ) .add( Projections.groupProperty("color") ) ) .list();
No es necesario ningún "group by" explícito en una consulta por criterios. Ciertos tipos de proyecciones son definidos para ser proyecciones agrupadas, que además aparecen en la cláusula SQL
group by
.An alias can be assigned to a projection so that the projected value can be referred to in restrictions or orderings. Here are two different ways to do this:
List results = session.createCriteria(Cat.class) .setProjection( Projections.alias( Projections.groupProperty("color"), "colr" ) ) .addOrder( Order.asc("colr") ) .list();
List results = session.createCriteria(Cat.class) .setProjection( Projections.groupProperty("color").as("colr") ) .addOrder( Order.asc("colr") ) .list();
Los métodos
alias()
y as()
simplemente envuelven una instancia de proyección en otra instancia deProjection
con alias. Como un atajo, puedes asignar un alias cuando agregas la proyección a una lista de proyecciones:List results = session.createCriteria(Cat.class) .setProjection( Projections.projectionList() .add( Projections.rowCount(), "catCountByColor" ) .add( Projections.avg("weight"), "avgWeight" ) .add( Projections.max("weight"), "maxWeight" ) .add( Projections.groupProperty("color"), "color" ) ) .addOrder( Order.desc("catCountByColor") ) .addOrder( Order.desc("avgWeight") ) .list();
List results = session.createCriteria(Domestic.class, "cat") .createAlias("kittens", "kit") .setProjection( Projections.projectionList() .add( Projections.property("cat.name"), "catName" ) .add( Projections.property("kit.name"), "kitName" ) ) .addOrder( Order.asc("catName") ) .addOrder( Order.asc("kitName") ) .list();
Puedes también usar
Property.forName()
para expresar proyecciones:List results = session.createCriteria(Cat.class) .setProjection( Property.forName("name") ) .add( Property.forName("color").eq(Color.BLACK) ) .list();
List results = session.createCriteria(Cat.class) .setProjection( Projections.projectionList() .add( Projections.rowCount().as("catCountByColor") ) .add( Property.forName("weight").avg().as("avgWeight") ) .add( Property.forName("weight").max().as("maxWeight") ) .add( Property.forName("color").group().as("color" ) ) .addOrder( Order.desc("catCountByColor") ) .addOrder( Order.desc("avgWeight") ) .list();
The
A
Correlated subqueries are also possible:
DetachedCriteria
class allows you to create a query outside the scope of a session and then execute it using an arbitrary Session
.DetachedCriteria query = DetachedCriteria.forClass(Cat.class) .add( Property.forName("sex").eq('F') ); Session session = ....; Transaction txn = session.beginTransaction(); List results = query.getExecutableCriteria(session).setMaxResults(100).list(); txn.commit(); session.close();
A
DetachedCriteria
can also be used to express a subquery. Criterion instances involving subqueries can be obtained via Subqueries
or Property
.DetachedCriteria avgWeight = DetachedCriteria.forClass(Cat.class) .setProjection( Property.forName("weight").avg() ); session.createCriteria(Cat.class) .add( Property.forName("weight").gt(avgWeight) ) .list();
DetachedCriteria weights = DetachedCriteria.forClass(Cat.class) .setProjection( Property.forName("weight") ); session.createCriteria(Cat.class) .add( Subqueries.geAll("weight", weights) ) .list();
Correlated subqueries are also possible:
DetachedCriteria avgWeightForSex = DetachedCriteria.forClass(Cat.class, "cat2") .setProjection( Property.forName("weight").avg() ) .add( Property.forName("cat2.sex").eqProperty("cat.sex") ); session.createCriteria(Cat.class, "cat") .add( Property.forName("weight").gt(avgWeightForSex) ) .list();
For most queries, including criteria queries, the query cache is not efficient because query cache invalidation occurs too frequently. However, there is a special kind of query where you can optimize the cache invalidation algorithm: lookups by a constant natural key. In some applications, this kind of query occurs frequently. The criteria API provides special provision for this use case.
First, map the natural key of your entity using
This functionality is not intended for use with entities with mutable natural keys.
Once you have enabled the Hibernate query cache, the
First, map the natural key of your entity using
and enable use of the second-level cache.This functionality is not intended for use with entities with mutable natural keys.
Once you have enabled the Hibernate query cache, the
Restrictions.naturalId()
allows you to make use of the more efficient cache algorithm.session.createCriteria(User.class) .add( Restrictions.naturalId() .set("name", "gavin") .set("org", "hb") ).setCacheable(true) .uniqueResult();
2 comentarios:
Disculpa que tipo de dato es "sess"... y como lo inicializo??
Disculpa que tipo de dato es el "sess".. y como la inicializo??
Publicar un comentario