Hibernate 的Criteria

1. Criteria

Hibernate has designed CriteriaSpecification as the parent interface of Criteria. Criteria and DetachedCriteria are provided below.
2. DetachedCriteria
Spring's framework provides getHibernateTemplate().findByCriteria(detachedCriteria) method, which can easily return query results according to DetachedCriteria. DetachedCriteria provides two static methods forClass(Class) or forEntityName(Name) to create a DetachedCriteria instance.
3. Comparison
   of Criteria and DetachedCriteria 3.1. The main difference between Criteria and DetachedCriteria is that the form of creation is different.

    Criteria is online and is created by Hibernate Session; while DetachedCriteria is offline and does not require Session when creating;



   3.2, Criteria is tied to Session Certainly, its life cycle ends with the end of the session. When querying using Criteria, objects must be dynamically created during the execution period each time, and various query conditions must be added. As the Session is recycled, the Criteria is also recycled.

   3.3, Criteria and DetachedCriteria can use Criterion and Projection to set query conditions. You can set FetchMode (the mode of joint query fetching), and set the sorting method. For Criteria, you can also set FlushModel (the way to flush Session) and LockMode (database lock mode).
4. Criterion and Projection
  4.1. Concept
  Criterion is the query condition of Criteria. Criteria provides the add(Criterion criterion) method to add query criteria.
  The main implementations of the Criterion interface include: Example , Junction , and SimpleExpression .
   The actual use of Junction is its two subclasses, conjunction and disjunction, which use AND and OR operators respectively to join query condition sets.
  4.2. Create
  Criterion instances can be created through the Restrictions tool class. Restrictions provides a large number of static methods, such as eq (equal to), ge (greater than or equal to), between and other methods to create Criterion query conditions (SimpleExpression instances). In addition, Restrictions also provides methods to create instances of conjunction and disjunction, and add query conditions to form a query condition set through the add(Criteria) method of the instance.
  As for the creation of Example is different, Example itself provides a static method create(Object entity), that is, it is created according to an object (in actual use, it is generally an object mapped to the database). Then you can set some
filter conditions:
  Example exampleUser =Example.create(u).ignoreCase() // Ignore
  case.enableLike(MatchMode.ANYWHERE);// For properties of type String, match no matter where the value is there.

Equivalent to %value%


  Project mainly allows Criteria to perform report query and grouping. Project mainly has three implementations: SimpleProjection, ProjectionList and Property. The instantiation of SimpleProjection and ProjectionList is done by built-in Projections, such as avg , count , max , min , sum provided, which allows developers to easily perform statistical query on a field.
  Property is the setting of query conditions for a field, such as through Property.forName("color").in
(new String[]{"black","red","write"}); You can create a Project instance . Add to the query conditions through the add(Project) method of the criterion.



5. Specific usage
When using Criteria for query, the main thing to be clear is that Hibernate provides those classes and methods to satisfy the query in development.
The creation and assembly of query conditions are described below:
  5.1. Create a Criteria instance
The org.hibernate.Criteria interface represents a query of a specific persistent class. Session is a factory for Criteria instances.
Criteria crit = sess.createCriteria(Cat.class);
crit.setMaxResults(50);
List cats = crit.list();

  5.2. Set the query condition
   List cats = sess.createCriteria(Cat.class) .add
   ( Restrictions.like ("name", "Fritz%") )//Set query conditions.add
   ( Restrictions.or(Restrictions.eq( "age", new Integer(0) ),Restrictions.isNull("age")) )// Logical condition.add

   ( Restrictions.disjunction()//Set multiple conditions.add
   ( Restrictions.isNull("age") )
   .add( Restrictions.eq("age", new Integer(0) ) )
   .add( Restrictions. eq("age", new Integer(1) ) )
   .

   .list(); The setMaxResults() method of the



   paging query

   Criteria can set the maximum result set of the query, and setFirstResult() sets the starting position of the query. Simple paging
   Criteria criteria = session.createCriteria can be achieved through the above two methods (User.class);
   criteria.setFirstResult(1).criteria.setMaxResults(10).list();



   Hibernate provides quite a few built-in criterion types (Restrictions subclasses), but especially useful ones allow you to use SQL directly .
  Criteria criteria = session.createCriteria(Cat.class)
  criteria .add( Restrictions.sql("lower({alias}.name) like lower(?)", "Fritz%", Hibernate.STRING) ).list();

   The {alias} placeholder should be replaced with the column alias of the queried entity.



The common conditions of Restrictions are shown:

Restrictions.eq --> equal, equal.

Restrictions.allEq --> The parameter is a Map object, using key/value to perform multiple equal comparisons, which is equivalent to the effect of multiple Restrictions.eq

Restrictions .gt --> great-than > greater than

Restrictions.ge --> great-equal >= greater than or equal to

Restrictions.lt --> less-than, < less than

Restrictions.le --> less-equal <= less than or equal to

Restrictions.between --> corresponding to the between clause of SQL

Restrictions.like --> corresponding to the LIKE clause of SQL

Restrictions.in --> corresponding to the in clause of SQL

Restrictions.and --> and relation

Restrictions.or --> or relation

Restrictions.isNull --> determine whether the attribute is Empty, return true if it is empty, which is equivalent to is null in SQL

Restrictions.isNotNull --> opposite to isNull, equivalent to is not null in SQL

Restrictions.sqlRestriction --> SQL-qualified query

Order.asc --> According to the incoming field Sort ascending order

Order.desc --> Sort descending order according to the incoming field

MatchMode.EXACT --> String exact match. Equivalent to "like 'value'"

MatchMode.ANYWHERE --> String matches in the middle. Equivalent to "like '%value%' "

MatchMode.START --> the string is in the first position. Equivalent to "like 'value%'"

MatchMode.END --> The string is in the last position. Equivalent to "like '%value'"



Property


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();



5.3. Result set ordering

You can use org.hibernate.criterion.Order to order query results.
List cats = sess.createCriteria(Cat.class) .add
( Restrictions.

.addOrder( Order.desc("age") )
.setMaxResults(50)
.list();

List cats = sess.createCriteria(Cat.class) .add
(Restrictions.liek("name", "F",MatchMode. ANYWHERE));
.addOrder( Property.forName("name").asc() )
.addOrder( Property.forName("age").desc() )
.setMaxResults(50)
.list();

5.4 Association
You can It is very easy to create constraints between related entities using createCriteria().

List cats = sess.createCriteria(Cat.class) .add
( Restrictions.like("name", "F%")
.createCriteria("kittens") .add
  ( Restrictions.like("name", "F%")
.list();

Note that the second createCriteria() returns a new Criteria instance that references the elements in the kittens collection.
Next, alternate forms are also useful in certain situations.

List cats = sess.createCriteria(Cat.class)
.createAlias("kittens", "kt")
.createAlias("mate", "mt")
.add( Restrictions.eqProperty("kt.name", "mt.name" ") )
.list();

(createAlias() does not create a new Criteria instance.)
The set of kittens returned by the previous two queries held by the Cat instance is not pre-filtered by the condition. If you want to get only eligible kittens, you must use returnMaps().
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);



5.5. Dynamic associative fetching
You can use setFetchMode() to define the semantics of dynamic associative fetching at runtime.

List cats = sess.createCriteria(Cat.class) .add
( Restrictions.like("name", "Fritz%") )
.setFetchMode("mate", FetchMode.EAGER)
.setFetchMode("kittens", FetchMode.EAGER)
.list();

This query can grab mate and kittens via outer join.

5.6, Example
The org.hibernate.criterion.Example class allows you to construct a conditional query from a given instance.
Cat cat = new Cat();
cat.setSex('F');
cat.setColor(Color.BLACK);
List results = session.createCriteria(Cat.class) .add
( Example.create(cat) )
.list( );

version attributes, identifiers, and associations are ignored. Properties with a value of null by default will be excluded. You can adjust the Example to make it more practical.

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();


You can even use examples to put conditions on associated objects.

List results = session.createCriteria(Cat.class) .add
( Example.create(cat) )
.createCriteria("mate")
  .add( Example.create( cat.getMate() ) )
.list();


5.7. Projection (Projections), aggregation (aggregation) and grouping (grouping)
org.hibernate.criterion.Projections is an instance factory for Projection. We apply 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();


There is no need to explicitly use "group by" in a conditional query. Certain projection types are defined as grouping projections, and

they also appear in SQL's group by clause.

An alias can optionally be assigned to a projection, which allows the projection values ​​to be referenced by constraints or orderings. Here are two different

implementations :

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(); The

alias() and as() methods simply wrap a projection instance to another aliased Projection instance. In short,

when you add a projection to a projection list you can assign it an alias:

List results = session.createCriteria(Cat.class)
.setProjection( Projections.projectionList() .add(
  Projections.rowCount( ), "catCountByColor" ) .add
  ( Projections.avg("weight"), "avgWeight" ) .add
  ( Projections.max("weight"),
  .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();


也可以使用Property.forName()来表示投影:

List results = session.createCriteria(Cat.class)
.setProjection( Property.forName("name") )




















.add( Property.forName("sex").eq('F') );
//Create a Session
Session session = .;
Transaction txn = session.beginTransaction();
List results = query.getExecutableCriteria(session).setMaxResults (100).list();
txn.commit();
session.close();


DetachedCriteria can also be used to express subqueries. Condition instances containing subqueries can be obtained through 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();

相互关联的子查询也是有可能的:

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();

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326524015&siteId=291194637