Hibernate Criteria API

A Hibernate – relációs/objektumrelációs perzisztenciakezelést megvalósító eszközrendszer – rendelkezik egy Criteria nevű keretrendszerrel, amely arra szolgál, hogy segítségével objektumorientált módon lehet lekérdezéseket megfogalmazni olyan módon, hogy az entitásokhoz bizonyos feltételeket, kritériumokat definiálunk.

Criteria példányok létrehozása

Az org.hibernate.Criteria interfész alkotja a lekérdezést, melynek példányai a Session objektumokból jönnek létre.

Criteria criteria = session.createCriteria(Person.class).setMaxResults(30);
List people = criteria.list();

A Criteria interfész néhány metódusa:

  • add(Criterion criterion)
  • addOrder(Order order)
  • list()
  • getAlias()
  • createAlias(String associationPath, String alias)
  • setFirstResult(int firstResult)
  • setMaxResults(int maxResults)
  • setProjection(Projection projection)

Eredményhalmaz szűkítése

Restrictions

Az org.hibernate.criterion.Restrictions (restiction = korlátozás) interfész metódusai a lekérdezések eredményhalmazát különböző megszorításokkal szűkítik. A Restictions osztály metódusai hasonló szűréseket valósítanak meg, mint amik az SQL lekérdező nyelvekből ismertek.

A Restrictions interfész néhány metódusa:

  • like(String propertyName, Object value)
  • between(String propertyName, Object lo, Object hi)
  • or(Criterion lhs, Criterion rhs)
  • and(Criterion lhs, Criterion rhs)
  • eq(String propertyName, Object value) (equal)
  • ge(String propertyName, Object value) (greater than or equal)
  • gt(String propertyName, Object value) (greater then)
  • isEmpty(String propertyName)
  • isNull(String propertyName)
  • disjunction() (A vagy B vagy C...)
  • conjunction() (A és B és C...)

Példák:

List people = session.createCriteria(Person.class)
    .add( Restrictions.like("birthplace", "London") )
    .add( Restrictions.between("age", minAge, maxAge) )
    .list();

A kritériumok logikai csoportosítása diszjunkcióval:

List people = session.createCriteria(Person.class)
    .add( Restrictions.in( "birthplace", new String[] { "London", "Bristol", "Oxford" } ) )
    .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();

Lehet beépíteni közvetlenül SQL szűréseket is a lekérdezésekbe.

List people = session.createCriteria(Person.class)
    .add(Restrictions.sqlRestriction("lower({alias}.birthPlace) like lower(?)", "London", Hibernate.STRING) )
    .list();

Property

Az org.hibernate.criterion.Property (property = tulajdonság) osztály forName() metódusával saját nevet adhatunk meg az entitás tulajdonságainak.

Példa:

Property age = Property.forName("age");
List people = session.createCriteria(Person.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) ) )
		) )
		.list();

Eredmények rendezése

Order

Az org.hibernate.criterion.Order interfész felhasználásával lehet rendezni az eredményhalmazt.

Az Order interfész néhány metódusa:

  • asc(String propertyName) ( ascending order – növekvő rendezés)
  • desc(String propertyName) ( descending order – csökkenő rendezés)
List people= session.createCriteria(Person.class)
    .add( Restrictions.like("name", M%")
    .addOrder( Order.asc("name") )
    .addOrder( Order.desc("age") )
    .setMaxResults(50)
    .list();

Asszociáció

Egymáshoz kapcsolódó entitásokra vonatkozó lekérdezések.

List people = session.createCriteria(Person.class)
    .add( Restrictions.like("name", "M%") )
    .createCriteria("kids")
        .add( Restrictions.like("name", "M%") )
    .list();

A második createCriteria() egy új Criteria példánnyal tér vissza, mely a ”kids” (másik entitás) kollekció példányaira hivatkozik.
Van egy másik formája is az asszociáció létrehozásának. Ha a createCriteria() helyett a createAlias(”masik_entitas”,”aliasnev”) metódust adjuk meg, amelyben az ”aliasnev” -vel hivatkozunk a ”masik_entitas” entitásunkra.

List people = session.createCriteria(Person .class)
    .createAlias("kids", "k")
    .createAlias("adults", "a")
    .add( Restrictions.eqProperty("k.name", "a.name") )
    .list();

A setFetchMode() segítségével állíthatjuk be, hogy melyik osztály milyen módon kerüljön betöltésre. Létezik FetchMode.EAGER és FetchMode.LAZY, azaz gyors és lassú kapcsolási mód.

List people= session.createCriteria(Person.class)
    .add( Restrictions.like("name", "M%") )
    .setFetchMode("adults", FetchMode.EAGER)
    .setFetchMode("kids", FetchMode.EAGER)
    .list();

Objektum példány beágyazása a lekérdezésbe

Example

Az org.hibernate.criterion.Example interfész lehetővé teszi, hogy egy objektum példányból állítsuk össze lekérdezést.

Példa:

Person p = new Person();
p.setAge(5);
p.setBirthPlace(London);

List results = session.createCriteria(Person.class)Projection
		.add( Example.create(p) )
		.list();

Vagy adhatunk hozzá további kritériumokat a következőképpen:

Example example = Example.create(p)
	.excludeZeroes() 
	.excludeProperty("name") 
	.ignoreCase() 
	.enableLike();

List results = session.createCriteria(Person.class)
		.add( example )
		.list();

Eredményhalmaz megjelenítése

Projection

A Criteria interfész setProjection() metódusával tudjuk beállítani a megjelenítési módokat. Paraméterül adva neki egy org.hibernate.criterion.Projections példányt.

A Projections néhány megtódusa:

  • alias(Projection projection, String alias)
  • avg(String propertyName)
  • count(String propertyName)
  • distinct(Projection proj)
  • groupProperty(String propertyName)
  • max(String propertyName)
  • min(String propertyName)
  • rowCount()
  • sum(String propertyName)

Példa:

List rows = session.createCriteria(Person.class)
    .setProjection( Projections.rowCount() )
    .add( Restrictions.eq("name", M%) )
    .list();
List results = session.createCriteria(Person.class)
    .setProjection( Projections.projectionList()
        .add( Projections.rowCount() )
        .add( Projections.avg("age") )
        .add( Projections.max("height") )
        .add( Projections.groupProperty("birthplace") )
    )
    .list();

Itt szintén megadhatunk saját nevet annak a tulajdonságnak, ami alapján csoportosítunk. Két -féle módon tehetjük meg.

List results = session.createCriteria(Person.class)
    .setProjection( Projections.alias( Projections.groupProperty("birthplace"), "bp" ) )
    .addOrder( Order.asc("bp") )
    .list();
List results = session.createCriteria(Person.class)
    .setProjection( Projections.groupProperty("birthplace").as("bp") )
    .addOrder( Order.asc("bp") )
    .list();

Különálló lekérdezések

DetachedCriteria

A org.hibernate.criterion.DetachedCriteria interfésszel lehetőségünk van arra, hogy a session s scope-ján kívül készítstünk lekérdezéseket. A DetachedCriteria egy allekérdezést fejez ki, létrehozása után (DetachedCriteria.forClass(...)) közel azok a metódusok használhatóak, mint a createCriteria() esetében.

DetachedCriteria query = DetachedCriteria.forClass(Person.class)
    .add( Property.forName("birthPlace").eq(London) );
    
Session session = ....;
Transaction txn = session.beginTransaction();
List results = query.getExecutableCriteria(session).setMaxResults(100).list();
txn.commit();
session.close();

Források

  • querycriteria
  • the-criteria-API
  • Informatika Informatikai portál • összefoglaló, színes tartalomajánló lap