Essentials
Get Involved
Documentation
Howto Guides
Development
|
Advanced Criteria Techniques
|
|
For a basic description and examples of the Criteria Object with Peers please
view the Peers Howto
document. 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);
|
 |
 |
 |
 |
|
|
|