Java
  Home arrow Java arrow Page 3 - Hibernate: Criteria Queries in Depth
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Moblin 
JMSL Numerical Library 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
JAVA

Hibernate: Criteria Queries in Depth
By: A.P.Rajshekhar
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 61
    2006-03-15

    Table of Contents:
  • Hibernate: Criteria Queries in Depth
  • The Core Classes of Criteria Queries
  • Using Criteria Queries
  • A Criteria Query in the Real World

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Hibernate: Criteria Queries in Depth - Using Criteria Queries


    (Page 3 of 4 )

    Now that the common core classes have been introduced, their usage in applications can be discussed. I already said in the last article that in SQL, DML plays  the most important role in the R(retrieve) operation of the CRUD quad. This is reflected in the core classes of Criteria API. The retrieval of data itself can be separated into four major categories:

    1. Projection

    2. Restriction

    3. Aggregation

    4. Grouping

    The usage of core classes among these categories cannot be generalized. The reason for this will be evident from the details. All the examples are based on the ORDER and PRODUCTS table.

    Do not confuse the term "Projection" as it is used here with the Projection class. Projection in common terms means to retrieve, and in SQL it means the "Select" clause. The "Select" clause is just a part of the services provided by the Projection class. Following is SQL query for projection of all fields of the ORDER table in SQL:

    SELECT * FROM ORDER

    The Criteria equivalent would be:

    List orders= session.createCriteria(Order.class).list();

    The above statement executes the corresponding SQL statement at the database server, populates the instances of the Order ORM class, adds them to a list and returns the List object. Actually, the above statement is composed of two statements:  

    Criteria criteria= session.createCriteria(Order.class)  and  

    List orders=criteria.list().

    The combination of such dependent statements is known as method chaining. From now on I will be using this technique extensively. The above code retrieves all the rows from the ORDER table. But what if only the data contained in one of the fields has to be retrieved, as in the following SQL query:

    SELECT NAME FROM PRODUCT

    Here, the Projection class comes into play. The above query can be rewritten into a Criteria query as:

    List products=session.createCriteria(Product.class)
         . setProjection(Projection.property(\"name\"))
         .list();

    It is clear from the above example that to query based on just one field, the fieldname is passed as an argument to the property() method of the Projection class. The Projection instance returned in turn becomes an argument to the setProjection() method. Similarly, to retrieve data based on two fields, ProjectionList has to be used. Hence the SQL query:

    SELECT NAME, ID FROM PRODUCT

    Would become

    List products =session.createCriteria(Product.class).setProjection(
        Projections.propertyList()
            .add(Projection.property(\"name\"))
            .add(Projection.property(\"id\"))
        )
        .list();

    Now let's make the query more complex by introducing joins. What would be the equivalent of a query such as the one below:

    SELECT O.*, P.* FROM ORDERS O, PRODUCT P WHERE O.ORDER_ID=P.ORDER_ID;

    If you think the Criteria representation of the above would be as complex, then have a look at the following:

    List orders = session.createCriteria(Order.class)
                .setFetchMode(“products”,FetchMode.JOIN)
                .list();

    It's as simple as that. The only thing to be done is to call the setFetchMode() of the Criteria class with two parameters: the name of the class with which the current class has to be joined and mode of the fetching of the data from the associated class. In the above case, the class name is actually the instance variable provided within the Order class. The mode is Join.

    So retrieval is done, but there is just one problem. If the data has to be retrieved based on a condition, then what? Then Restriction has to be used.

    In layman’s terms, restriction means imposing conditions. To retrieve data based on certain conditions, Restriction must be used. Here the Restriction class comes into the picture. All the conditions provided by SQL are available in Criteria. The ones most commonly used are as follows:

    Restriction.between is used to apply a "between" constraint to the field.

    Restriction.eq is used to apply an "equal" constraint to the field.

    Restriction.ge is used to apply a "greater than or equal" constraint to the field.

     Restriction.gt is used to apply a "greater than" constraint to the field.

    Restriction.idEq is used to apply an "equal" constraint to the identifier property.

    Restriction.in is used to apply an "in" constraint to the field.

    Restriction.isNotNull is used to apply an "is not null" constraint to the field.  

    Restriction.isNull is used to apply an "is null" constraint to the field.

    Restriction.ne is used to apply a "not equal" constraint to the field.     

         So a SQL such as this

         SELECT * FROM ORDERS WHERE ORDER_ID=’1092’;

          Would become   

        List orders= session.createCriteria(Order.class)
                   .add(Restrictions.eq(“orderId”,”1092”))
                   .list();

    Applying the restrictions becomes easy in the case of joins as well. For example, the following query

        SELECT O.*, P.* FROM ORDERS O, PRODUCT P WHERE

        O.ORDER_ID=P.ORDER_ID AND P.ID=’1111’;

    Would become

    List orders = session.createCriteria(Order.class)
            .setFetchMode(“products”,FetchMode.JOIN)
            .add(Restrictions.eq(“id”,”1111”))
            .list();

    Just adding the Restriction to Criteria returned by setFetchMode() does the same thing that the above given SQL does.

    Through restriction conditions can be imposed on data retrieval, there are situations where the data to be retrieved has to be based on the groups of values of a column. In such conditions, Aggregation must be used. Criteria provides aggregation functionality through the Projection class itself. So to get the count of all the rows present in the ORDER table based on the ID field, the criteria query would be:

    List orders = session.createCriteria(Order.class)
         .setProjection( Projections.projectionList()
         .add( Projections.count(“id”) ))
         .list();

    Similarly all the aggregate functions can be used as they are provided as static functions. As shown in the above example, each function takes the field name as the argument.

    When the aggregation functions are used, the values may have to be grouped according to a particular field. Grouping always operates on a dataset. In Criteria Query API, grouping is provided by the Projection class. The groupProperty() method of the Projections class provides the grouping functionality. So a query like the one given below:

    SELECT COUNT(ID) FROM ORDER  HAVING PRICETOTAL>2000 GROUP BY ID

     Can be rewritten in Criteria query as follows:

    List orders = session.createCriteria(Order.class)
         .setProjection( Projections.projectionList()
          .add( Projections.count(“id”) )
           .add( Projections.groupProperty(“id”) )
         )
          .list();

    That brings us to the end of this section. In the next section I will be using the Criteria query APIs to rewrite the application written in the last part.

    More Java Articles
    More By A.P.Rajshekhar


       · HiHQL is not suitable at all times. Thats why Criteria APIs were introduced. In...
       · This article is helpful.But your example doesn't elaborate on the HAVING?I would...
       · Thats exactly what I was thinking. He did actually reproduce that query using the...
       · Having is not supported by Hibernate 2.x and in 3.1 if the criteria after having is...
     

    JAVA ARTICLES

    - Deploying Multiple Java Applets as One
    - Deploying Java Applets
    - Understanding Deployment Frameworks
    - Database Programming in Java Using JDBC
    - Extension Interfaces and SAX
    - Entities, Handlers and SAX
    - Advanced SAX
    - Conversions and Java Print Streams
    - Formatters and Java Print Streams
    - Java Print Streams
    - Wildcards, Arrays, and Generics in Java
    - Wildcards and Generic Methods in Java
    - Finishing the Project: Java Web Development ...
    - Generics and Limitations in Java
    - Getting Started with Java Web Development in...






    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 5 hosted by Hostway
    Stay green...Green IT