Essentials
Models
Get Involved
Documentation
Database
|
Advanced Criteria Techniques
|
For a basic description and examples of the Criteria Object with Peers please view the Peers and Advanced Peers documents. This document intends to show more advanced techniques using Criteria, such as comparators and joins. As always, for more information on the methods available in the Criteria Object, view the javadocs.
|
Using Criteria to create Joins
|
This example will use the related tables in the Turbine Security system between the Turbine_Role and Turbine_Permission tables, with the bridging table, Turbine_Role_Permission. The relationship between these tables are in the Core Schema document, with Turbine_Role and Turbine_Permission both having a one-to-many relationships with Turbine_Role_Permission table. As Role exists as a container for Permissions, one requirement that may be desired for an application is to show a list of the Permissions in a Role. Please note though, that this is for the sake of example, the Role Object in the org.apache.turbine.om.security package contains a convenience method getPermissions() which will achieve pretty much the same objective. The following is used as an example as it is a relatively familiar problem and uses components that are part of the core Turbine system.
Create the Criteria Object;
 |
 |
 |
 |
Criteria criteria = new Criteria();
criteria.addJoin(PermissionPeer.PERMISSION_ID,RolePermissionPeer.PERMISSION_ID);
criteria.addJoin(RolePermissionPeer.ROLE_ID, RolePeer.ROLE_ID);
Vector v = RolePeer.doSelect(criteria);
|
 |
 |
 |
 |
The addJoin() method works by joining the tables left to right, the above criteria will return all the Roles that have a Permission. To view the output of the criteria, print it out with criteria.toString().
If instead though we want to view all the Permissions that are connected to a Role we would reverse the join via;
 |
 |
 |
 |
Criteria criteria = new Criteria();
criteria.addJoin(RolePeer.ROLE_ID,RolePermissionPeer.ROLE_ID);
criteria.addJoin(RolePermissionPeer.PERMISSION_ID, PermissionPeer.PERMISSION_ID);
Vector v = PermissionPeer.doSelect(criteria);
|
 |
 |
 |
 |
|
Using the Comparators in Criteria
|
The Criteria Object has the following camparators;
Criteria.ALT_NOT_EQUAL
Criteria.CUSTOM
Criteria.DISTINCT
Criteria.EQUAL
Criteria.GREATER_EQUAL
Criteria.GREATER_THAN
Criteria.IN
Criteria.JOIN
Criteria.LESS_EQUAL
Criteria.LESS_THAN
Criteria.LIKE
Criteria.NOT_EQUAL
Criteria.NOT_IN
The comparators can be used to return results that satisfy the chosen comparisons. As an example, assume we have Invoice OM and Peer Objects that map to an invoice table in a database. The invoice table contains the columns, INVOICE_ID, COST, DATE and DESCRIPTION. Where the id is an integer, the cost a double, the date an mysql DATETIME and the Description a VARCHAR.
In the case of an invoice, we may need to know all the invoices that are above a certain limit. Where the limit is greater than $1000, this could be done via;
 |
 |
 |
 |
Criteria criteria = new Criteria();
criteria.add(InvoicePeer.COST, 1000, Criteria.GREATER_THAN);
Vector v = InvoicePeer.doSelect(criteria);
|
 |
 |
 |
 |
This will return a Vector of Invoice OM Objects which have cost values greater than $1000. The other comparitors work similarly and can be used in the same manner though many of the comparators are present as methods in the Criteria Object already, such as the Joins.
|
Simplifying Criteria
|
The Criteria Object can be verbose to use directly in your code. Often in an application the 80:20 rule applies when dealing with queries. The same 20% of queries are used 80% of the time. While Criteria and Criterion offer a tonne of flexibility, often having something simple to use is easier.
One way to achieve this is to create a class that extends Criteria and add convenience methods for your application or are specific to your database. In this case the example Object will be the SimpleCriteria with the methods that allow access to the examples above.
 |
 |
 |
 |
//Turbine
import org.apache.turbine.util.db.Criteria;
/**
* SimpleCriteria is a simple case of the more powerful Criteria
* Object.
*/
public class SimpleCriteria extends Criteria
{
/** currently used as DEFAULT_CAPACITY in Criteria is private */
private static final int DEFAULT_CAPACITY = 10;
/*
* Constructor
*/
public SimpleCriteria()
{
super(DEFAULT_CAPACITY);
}
/*
* Represents the Greater Than in the WHERE
* clause of an SQL Statement
*
* @param columnname the column name
* @param columnvalue the column value to be compared against
*/
public SimpleCriteria greaterThan(String columnname, int columnvalue)
{
super.add(columnname, columnvalue, Criteria.GREATER_THAN);
return this;
}
/*
* Represents the Is NULL in the WHERE
* clause of an SQL Statement
*
* @param columnname the column name
*/
public SimpleCriteria isNull(String columnname)
{
super.add(columnname, (columnname + " is NULL"), Criteria.CUSTOM);
return this;
}
/*
* Represents the Is NULL in the WHERE
* clause of an SQL Statement
*
* @param columnname the column name
*/
public SimpleCriteria isBetween(String columnname, int min, int max)
{
super.add(columnname, min, Criteria.GREATER_THAN);
super.Criterion criterion = criteria.getCriterion(columnname);
criterion.and(
super.getNewCriterion(
criterion.getTable(),
criterion.getColumn(),
new Integer(max),
Criteria.LESS_EQUAL )
);
return this;
}
}
|
 |
 |
 |
 |
This will simplify the code being written in the Business Objects or Actions and condense all the Criteria knowledge into the SimpleCriteria Object. The SimpleCriteria Object used in the same manner as Criteria. For example the initial
 |
 |
 |
 |
SimpleCriteria criteria = new SimpleCriteria();
criteria.isBetween(InvoicePeer.COST, 1000, 5000);
Vector v = InvoicePeer.doSelect(criteria);
|
 |
 |
 |
 |
|
|