View Javadoc

1   package org.apache.torque.criteria;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.Serializable;
23  import java.util.ArrayList;
24  import java.util.Collection;
25  import java.util.GregorianCalendar;
26  import java.util.HashMap;
27  import java.util.LinkedHashMap;
28  import java.util.List;
29  import java.util.Map;
30  
31  import org.apache.commons.lang.builder.EqualsBuilder;
32  import org.apache.commons.lang.builder.HashCodeBuilder;
33  import org.apache.torque.Column;
34  import org.apache.torque.sql.OrderBy;
35  import org.apache.torque.sql.Query;
36  import org.apache.torque.sql.SqlBuilder;
37  import org.apache.torque.util.UniqueColumnList;
38  import org.apache.torque.util.UniqueList;
39  
40  /**
41   * Encapsulates conditions to access rows in database tables.
42   *
43   * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a>
44   * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
45   * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a>
46   * @author <a href="mailto:eric@dobbse.net">Eric Dobbs</a>
47   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
48   * @author <a href="mailto:sam@neurogrid.com">Sam Joseph</a>
49   * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
50   * @author <a href="mailto:fischer@seitenbau.de">Thomas Fischer</a>
51   * @author <a href="mailto:seade@backstagetech.com.au">Scott Eade</a>
52   * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
53   * @version $Id: Criteria.java 1397355 2012-10-11 22:52:33Z tfischer $
54   */
55  public class Criteria
56          implements Serializable, Cloneable, CriteriaInterface<Criteria>
57  {
58      /** Serial version. */
59      private static final long serialVersionUID = -9001666575933085601L;
60  
61      /** Comparison type. */
62      public static final SqlEnum EQUAL = SqlEnum.EQUAL;
63  
64      /** Comparison type. */
65      public static final SqlEnum NOT_EQUAL = SqlEnum.NOT_EQUAL;
66  
67      /** Comparison type. */
68      public static final SqlEnum ALT_NOT_EQUAL = SqlEnum.ALT_NOT_EQUAL;
69  
70      /** Comparison type. */
71      public static final SqlEnum GREATER_THAN = SqlEnum.GREATER_THAN;
72  
73      /** Comparison type. */
74      public static final SqlEnum LESS_THAN = SqlEnum.LESS_THAN;
75  
76      /** Comparison type. */
77      public static final SqlEnum GREATER_EQUAL = SqlEnum.GREATER_EQUAL;
78  
79      /** Comparison type. */
80      public static final SqlEnum LESS_EQUAL = SqlEnum.LESS_EQUAL;
81  
82      /** Comparison type. */
83      public static final SqlEnum LIKE = SqlEnum.LIKE;
84  
85      /** Comparison type. */
86      public static final SqlEnum NOT_LIKE = SqlEnum.NOT_LIKE;
87  
88      /** Comparison type. */
89      public static final SqlEnum ILIKE = SqlEnum.ILIKE;
90  
91      /** Comparison type. */
92      public static final SqlEnum NOT_ILIKE = SqlEnum.NOT_ILIKE;
93  
94      /** Comparison type. */
95      public static final SqlEnum DISTINCT = SqlEnum.DISTINCT;
96  
97      /** Comparison type. */
98      public static final SqlEnum IN = SqlEnum.IN;
99  
100     /** Comparison type. */
101     public static final SqlEnum NOT_IN = SqlEnum.NOT_IN;
102 
103     /** Comparison type. */
104     public static final SqlEnum ALL = SqlEnum.ALL;
105 
106     /** Comparison type. */
107     public static final SqlEnum JOIN = SqlEnum.JOIN;
108 
109     /** &quot;IS NULL&quot; null comparison */
110     public static final SqlEnum ISNULL = SqlEnum.ISNULL;
111 
112     /** &quot;IS NOT NULL&quot; null comparison */
113     public static final SqlEnum ISNOTNULL = SqlEnum.ISNOTNULL;
114 
115     /** &quot;CURRENT_DATE&quot; ANSI SQL function */
116     public static final SqlEnum CURRENT_DATE = SqlEnum.CURRENT_DATE;
117 
118     /** &quot;CURRENT_TIME&quot; ANSI SQL function */
119     public static final SqlEnum CURRENT_TIME = SqlEnum.CURRENT_TIME;
120 
121     /** &quot;CURRENT_TIMESTAMP&quot; ANSI SQL function */
122     public static final SqlEnum CURRENT_TIMESTAMP = SqlEnum.CURRENT_TIMESTAMP;
123 
124     /** &quot;LEFT JOIN&quot; SQL statement */
125     public static final JoinType LEFT_JOIN = JoinType.LEFT_JOIN;
126 
127     /** &quot;RIGHT JOIN&quot; SQL statement */
128     public static final JoinType RIGHT_JOIN = JoinType.RIGHT_JOIN;
129 
130     /** &quot;INNER JOIN&quot; SQL statement */
131     public static final JoinType INNER_JOIN = JoinType.INNER_JOIN;
132 
133     /** Whether to ignore the case in all String conditions in the criteria. */
134     private boolean ignoreCase = false;
135 
136     /** Whether the result must be a single record. */
137     private boolean singleRecord = false;
138 
139     /** List of modifiers like DISTICT. */
140     private final UniqueList<String> selectModifiers = new UniqueList<String>();
141 
142     /** List of all columns to select. */
143     private final UniqueColumnList selectColumns = new UniqueColumnList();
144 
145     /** All "order by" clauses, containing the order ASC or DESC. */
146     private final UniqueList<OrderBy> orderByColumns = new UniqueList<OrderBy>();
147 
148     /** The names of columns to add to a groupBy clause */
149     private final UniqueColumnList groupByColumns = new UniqueColumnList();
150 
151     /**
152      * All "from" clauses. Empty if the from clause should be computed
153      * automatically.
154      */
155     private final UniqueList<FromElement> fromElements
156             = new UniqueList<FromElement>();
157 
158     /** The having clause in a query. */
159     private Criterion having = null;
160 
161     /** The criterion objects, keyed by the column. */
162     private Criterion topLevelCriterion;
163 
164     /**
165      * Maps column alias names to the real column names.
166      * The key of the map is the alias and the value is the real column.
167      */
168     private final Map<String, Column> asColumns
169             = new LinkedHashMap<String, Column>();
170 
171     /** Contains all joins. */
172     private final List<Join> joins = new ArrayList<Join>();
173 
174     /** The name of the database in which this criteria should execute. */
175     private String dbName;
176 
177     /**
178      * To limit the number of rows to return.  <code>-1</code> means return all
179      * rows.
180      */
181     private int limit = -1;
182 
183     /** To start the results at a row other than the first one. */
184     private long offset = 0;
185 
186     /**
187      * Aliases for table names. The key of the map is the alias,
188      * and the value is either the real name of the table
189      * or a corresponding subselect.
190      */
191     private final Map<String, Object> aliases = new HashMap<String, Object>();
192 
193     /** The JDBC statement fetch size, if any. */
194     private Integer fetchSize;
195 
196     /**
197      * Creates a new instance with the default capacity.
198      */
199     public Criteria()
200     {
201         // empty
202     }
203 
204     /**
205      * Creates a new instance with the default capacity which corresponds to
206      * the specified database.
207      *
208      * @param dbName The database name.
209      */
210     public Criteria(String dbName)
211     {
212         this.dbName = dbName;
213     }
214 
215     /**
216      * Add an AS clause to the select columns. Usage:
217      * <p>
218      * <code>
219      * Criteria myCrit = new Criteria();
220      * myCrit.addAsColumn(
221      *     &quot;alias&quot;,
222      *     &quot;ALIAS(&quot;+MyPeer.ID+&quot;)&quot;);
223      * </code>
224      * If the name already exists, it is replaced by the new clause.
225      *
226      * @param name wanted Name of the column
227      * @param clause SQL clause to select from the table
228      *
229      * @return A modified Criteria object.
230      */
231     public Criteria addAsColumn(String name, Column clause)
232     {
233         asColumns.put(name, clause);
234         return this;
235     }
236 
237     /**
238      * Get the column aliases.
239      *
240      * @return A Map which map the column alias names
241      * to the alias clauses.
242      */
243     public Map<String, Column> getAsColumns()
244     {
245         return asColumns;
246     }
247 
248     /**
249      * Get the table aliases.
250      *
251      * @return A Map which maps the table alias names to either the actual
252      *         table names (String) or to a subselect (Criteria).
253      */
254     public Map<String, Object> getAliases()
255     {
256         return aliases;
257     }
258 
259     /**
260      * Allows one to specify an alias for a table.
261      *
262      * @param alias the alias for the table name.
263      * @param table the table name as known in the database.
264      */
265     public void addAlias(String alias, String table)
266     {
267         aliases.put(alias, table);
268     }
269 
270     /**
271      * Allows one to specify an alias for a subselect.
272      *
273      * @param alias the alias for the subselect.
274      * @param subselect the Criteria for the subselect.
275      */
276     public void addAlias(String alias, Criteria subselect)
277     {
278         aliases.put(alias, subselect);
279     }
280 
281     /**
282      * Returns the database table name associated with an alias.
283      *
284      * @param alias a <code>String</code> value.
285      *
286      * @return a <code>String</code> value, or null if the alias is not defined.
287      *
288      * @throws IllegalArgumentException if the alias with the name
289      *         <code>alias</code> is defined but is no alias for a table name
290      *         (e.g. it is an alias for a subselect).
291      */
292     public String getTableForAlias(String alias)
293     {
294         Object aliasResolved = aliases.get(alias);
295         if (aliasResolved == null)
296         {
297             return null;
298         }
299         if (aliasResolved instanceof String)
300         {
301             return (String) aliasResolved;
302         }
303         throw new IllegalArgumentException("The alias " + alias
304                 + " is not associated to a table but to an object of type "
305                 + alias.getClass().getName());
306     }
307 
308     /**
309      * Returns the subselect associated with an alias.
310      *
311      * @param alias a <code>String</code> value.
312      *
313      * @return a <code>String</code> value, or null if the alias is not defined.
314      *
315      * @throws IllegalArgumentException if the alias with the name
316      *         <code>alias</code> is defined but is not an alias for a subselect
317      *         (e.g. it is an alias for a table).
318      */
319     public Criteria getSubselectForAlias(String alias)
320     {
321         Object aliasResolved = aliases.get(alias);
322         if (aliasResolved == null)
323         {
324             return null;
325         }
326         if (aliasResolved instanceof Criteria)
327         {
328             return (Criteria) aliasResolved;
329         }
330         throw new IllegalArgumentException("The alias " + alias
331                 + " is not associated to a subselect but to an object of type "
332                 + alias.getClass().getName());
333     }
334 
335     /**
336      * Returns the top level Criterion.
337      *
338      * @return the top level Criterion, or null if no Criterion is contained.
339      */
340     public Criterion getTopLevelCriterion()
341     {
342         return topLevelCriterion;
343     }
344 
345     /**
346      * Get the Database name to be used for this criterion.
347      *
348      * @return The database name, may be null.
349      */
350     public String getDbName()
351     {
352         return dbName;
353     }
354 
355     /**
356      * Set the Database name.  The value <code>null</code> denotes the
357      * database name provided by <code>Torque.getDefaultDB()</code>
358      * (but this is not resolved here).
359      *
360      * @param dbName The Database(Map) name.
361      */
362     public void setDbName(String dbName)
363     {
364         this.dbName = dbName;
365     }
366 
367     /**
368      * This method adds a prepared Criterion object to the Criteria as a having
369      * clause. Usage:
370      * <p>
371      * <code>
372      * Criteria crit = new Criteria();
373      * Criterion c =new Criterion(MyPeer.ID, 5, Criteria.LESS_THAN);
374      * crit.addHaving(c);
375      * </code>
376      *
377      * @param having A Criterion object
378      * @return A modified Criteria object.
379      */
380     public Criteria addHaving(Criterion having)
381     {
382         this.having = having;
383         return this;
384     }
385 
386     /**
387      * Get Having Criterion.
388      *
389      * @return A Criterion that is the having clause.
390      */
391     public Criterion getHaving()
392     {
393         return having;
394     }
395 
396     /**
397      * Adds a join to the criteria, E.g. to create the condition
398      * <p>
399      * AND PROJECT.PROJECT_ID=FOO.PROJECT_ID
400      * <p> use <p>
401      * <code>
402      * criteria.addJoin(ProjectPeer.PROJECT_ID, FooPeer.PROJECT_ID)
403      * </code>
404      *
405      * @param left A String with the left side of the join.
406      * @param right A String with the right side of the join.
407      * @return A modified Criteria object.
408      */
409     public Criteria addJoin(Column left, Column right)
410     {
411         return addJoin(left, right, null);
412     }
413 
414     /**
415      * Adds a join to the criteria, E.g. to create the condition
416      * <p>
417      * PROJECT LEFT JOIN FOO ON PROJECT.PROJECT_ID=FOO.PROJECT_ID
418      * <p> use <p>
419      * <code>
420      * criteria.addJoin(ProjectPeer.PROJECT_ID, FooPeer.PROJECT_ID,
421      *     Criteria.LEFT_JOIN);
422      * </code>
423      *
424      * @param left A String with the left side of the join.
425      * @param right A String with the right side of the join.
426      * @param joinType The operator used for the join: must be one of null,
427      *        Criteria.LEFT_JOIN, Criteria.RIGHT_JOIN, Criteria.INNER_JOIN
428      * @return A modified Criteria object.
429      */
430     public Criteria addJoin(Column left, Column right, JoinType joinType)
431     {
432         joins.add(new Join(left, right, Criteria.EQUAL, joinType));
433 
434         return this;
435     }
436 
437     /**
438      * Adds a join to the criteria, E.g. to create the condition
439      * <p>
440      * PROJECT LEFT JOIN FOO ON PROJECT.PROJECT_ID=FOO.PROJECT_ID
441      * <p> use <p>
442      * <code>
443      * criteria.addJoin(
444      *     ProjectPeer.PROJECT_ID,
445      *     Criteria.NOT_EQUAL,
446      *     FooPeer.PROJECT_ID,
447      *     Criteria.LEFT_JOIN);
448      * </code>
449      *
450      * @param left A String with the left side of the join condition.
451      * @param right A String with the right side of the join condition.
452      * @param comparison the comparison operator, not null.
453      *        The operator CUSTOM is not supported.
454      * @param joinType The operator used for the join. Must be one of null,
455      *        Criteria.LEFT_JOIN, Criteria.RIGHT_JOIN, Criteria.INNER_JOIN
456      *
457      * @return A modified Criteria object.
458      */
459     public Criteria addJoin(
460             Column left,
461             Column right,
462             SqlEnum comparison,
463             JoinType joinType)
464     {
465         joins.add(new Join(left, right, comparison, joinType));
466 
467         return this;
468     }
469 
470     /**
471      * Adds a join to the criteria, E.g. to create the condition
472      * <p>
473      * PROJECT LEFT JOIN FOO ON PROJECT.PROJECT_ID=FOO.PROJECT_ID
474      * <p> use <p>
475      * <code>
476      * criteria.addJoin(
477      *     ProjectPeer.TABLE_NAME,
478      *     FooPeer.TABLE_NAME,
479      *     new Criterion(ProjectPeer.PROJECT_ID,
480      *         FooPeer.PROJECT_ID,
481      *         Criteria.NOT_EQUAL)
482      *     Criteria.LEFT_JOIN);
483      * </code>
484      *
485      * @param leftTable the left table of the join, or null to determine
486      *        the left table from the join condition.
487      * @param rightTable the left table of the join, or null to determine
488      *        the left table from the join condition.
489      * @param joinCondition the join condition, not null.
490      * @param joinType The operator used for the join. Must be one of null,
491      *        Criteria.LEFT_JOIN, Criteria.RIGHT_JOIN, Criteria.INNER_JOIN
492      *
493      * @return A modified Criteria object.
494      */
495     public Criteria addJoin(
496             String leftTable,
497             String rightTable,
498             Criterion joinCondition,
499             JoinType joinType)
500     {
501         joins.add(new Join(
502                 new PreparedStatementPart(leftTable),
503                 new PreparedStatementPart(rightTable),
504                 joinCondition,
505                 joinType));
506 
507         return this;
508     }
509 
510     /**
511      * Adds a join to the criteria, E.g. to create the condition
512      * <p>
513      * PROJECT LEFT JOIN FOO ON PROJECT.PROJECT_ID=FOO.PROJECT_ID
514      * <p> use <p>
515      * <code>
516      * criteria.addJoin(
517      *     new PreparedStatementPart(ProjectPeer.TABLE_NAME),
518      *     new PreparedStatementPart(FooPeer.TABLE_NAME),
519      *     new Criterion(ProjectPeer.PROJECT_ID,
520      *         FooPeer.PROJECT_ID,
521      *         Criteria.NOT_EQUAL)
522      *     Criteria.LEFT_JOIN);
523      * </code>
524      *
525      * @param leftTable the left table of the join, might contain an alias name,
526      *        or null to be determined from the join clause.
527      * @param rightTable the right table of the join, might contain an alias
528      *        name, or null to be determined from the join clause.
529      * @param joinCondition the join condition, not null.
530      * @param joinType The operator used for the join. Must be one of null,
531      *        Criteria.LEFT_JOIN, Criteria.RIGHT_JOIN, Criteria.INNER_JOIN
532      *
533      * @return A modified Criteria object.
534      */
535     public Criteria addJoin(
536             PreparedStatementPart leftTable,
537             PreparedStatementPart rightTable,
538             Criterion joinCondition,
539             JoinType joinType)
540     {
541         joins.add(new Join(
542                 leftTable,
543                 rightTable,
544                 joinCondition,
545                 joinType));
546 
547         return this;
548     }
549 
550     /**
551      * Get the List of Joins.
552      *
553      * @return a List which contains objects of type Join, not null.
554      */
555     public List<Join> getJoins()
556     {
557         return joins;
558     }
559 
560     /**
561      * Adds &quot;ALL &quot; to the SQL statement.
562      */
563     public void setAll()
564     {
565         selectModifiers.add(ALL.toString());
566     }
567 
568     /**
569      * Adds &quot;DISTINCT &quot; to the SQL statement.
570      */
571     public void setDistinct()
572     {
573         selectModifiers.add(DISTINCT.toString());
574     }
575 
576     /**
577      * Sets whether case should be ignored in where clauses and order by
578      * whenever String columns are encountered.
579      *
580      * @param ignoreCase True if case should be ignored.
581      * @return A modified Criteria object.
582      */
583     public Criteria setIgnoreCase(boolean ignoreCase)
584     {
585         this.ignoreCase = ignoreCase;
586         return this;
587     }
588 
589     /**
590      * Returns whether case should be ignored in where clauses and order by
591      * whenever String columns are encountered.
592      *
593      * @return True if case is ignored.
594      */
595     public boolean isIgnoreCase()
596     {
597         return ignoreCase;
598     }
599 
600     /**
601      * Switch the check on or off that a query returns exactly one record.
602      * Set this to <code>true</code> if you want a TorqueException to be thrown
603      * if none or multiple records are returned when the query is executed.
604      * This should be used in situations where returning multiple
605      * rows would indicate an error of some sort.  If your query might return
606      * multiple records but you are only interested in the first one then you
607      * should be using setLimit(1).
608      *
609      * @param b set to <code>true</code> if you expect the query to select
610      *        exactly one record.
611      * @return A modified Criteria object.
612      */
613     public Criteria setSingleRecord(boolean b)
614     {
615         singleRecord = b;
616         return this;
617     }
618 
619     /**
620      * Returns whether the check that a query returns exactly one record
621      * is active.
622      *
623      * @return True if the check for exactly one record is active.
624      */
625     public boolean isSingleRecord()
626     {
627         return singleRecord;
628     }
629 
630     /**
631      * Set a limit for the query
632      *
633      * @param limit The upper limit for the number of records returned
634      *        by a query.
635      * @return A modified Criteria object.
636      */
637     public Criteria setLimit(int limit)
638     {
639         this.limit = limit;
640         return this;
641     }
642 
643     /**
644      * Get the upper limit for the number of records returned by a query.
645      *
646      * @return The value for limit.
647      */
648     public int getLimit()
649     {
650         return limit;
651     }
652 
653     /**
654      * Set the offset.
655      *
656      * @param offset how many records should be skipped at the start of the
657      *        result.
658      * @return A modified Criteria object.
659      */
660     public Criteria setOffset(long offset)
661     {
662         this.offset = offset;
663         return this;
664     }
665 
666     /**
667      * Get how many records should be skipped at the start of the result.
668      *
669      * @return The value for offset.
670      */
671     public long getOffset()
672     {
673         return offset;
674     }
675 
676     /**
677      * Returns the JDBC statement fetch size to use for queries.
678      *
679      * @return the fetch size, or null if none is set.
680      */
681     public Integer getFetchSize()
682     {
683         return fetchSize;
684     }
685 
686     /**
687      * Sets the JDBC statement fetch size to use for queries.
688      *
689      * @param fetchSize the fetch size, or null for not set.
690      */
691     public void setFetchSize(Integer fetchSize)
692     {
693         this.fetchSize = fetchSize;
694     }
695 
696     /**
697      * Adds a select column to the Criteria.
698      *
699      * @param column The select column to add.
700      *
701      * @return A modified Criteria object.
702      */
703     public Criteria addSelectColumn(Column column)
704     {
705         selectColumns.add(column);
706         return this;
707     }
708 
709     /**
710      * Return all select columns.
711      *
712      * @return An List with the names of the select columns, not null
713      */
714     public UniqueColumnList getSelectColumns()
715     {
716         return selectColumns;
717     }
718 
719     /**
720      * Return all select modifiers.
721      *
722      * @return An UniqueList with the select modifiers.
723      */
724     public UniqueList<String> getSelectModifiers()
725     {
726         return selectModifiers;
727     }
728 
729     /**
730      * Add a group by clause.
731      *
732      * @param groupBy The column to group by.
733      *
734      * @return A modified Criteria object.
735      */
736     public Criteria addGroupByColumn(Column groupBy)
737     {
738         groupByColumns.add(groupBy);
739         return this;
740     }
741 
742     /**
743      * Get all group by columns.
744      *
745      * @return An UniqueList with the name of the groupBy clause, not null.
746      */
747     public UniqueColumnList getGroupByColumns()
748     {
749         return groupByColumns;
750     }
751 
752     /**
753      * Adds an order by clause, explicitly specifying ascending.
754      *
755      * @param column The column to order by.
756      *
757      * @return A modified Criteria object.
758      */
759     public Criteria addAscendingOrderByColumn(Column column)
760     {
761         orderByColumns.add(new OrderBy(column, SqlEnum.ASC, false));
762         return this;
763     }
764 
765     /**
766      * Add an order by clause, explicitly specifying ascending.
767      *
768      * @param column The column to order by.
769      * @param ignoreCase whether to ignore case on String columns.
770      *
771      * @return A modified Criteria object.
772      */
773     public Criteria addAscendingOrderByColumn(Column column, boolean ignoreCase)
774     {
775         orderByColumns.add(new OrderBy(column, SqlEnum.ASC, ignoreCase));
776         return this;
777     }
778 
779     /**
780      * Add order by column name, explicitly specifying descending.
781      *
782      * @param column The column to order by.
783      *
784      * @return A modified Criteria object.
785      */
786     public Criteria addDescendingOrderByColumn(Column column)
787     {
788         orderByColumns.add(new OrderBy(column, SqlEnum.DESC, false));
789         return this;
790     }
791 
792     /**
793      * Add order by column name, explicitly specifying descending.
794      *
795      * @param column The column to order by.
796      *
797      * @param ignoreCase whether to ignore case on String columns.
798      *
799      * @return A modified Criteria object.
800      */
801     public Criteria addDescendingOrderByColumn(
802             Column column,
803             boolean ignoreCase)
804     {
805         orderByColumns.add(new OrderBy(column, SqlEnum.DESC, ignoreCase));
806         return this;
807     }
808 
809     /**
810      * Get all order by columns.
811      *
812      * @return An UniqueList with the name of the order columns, not null.
813      */
814     public UniqueList<OrderBy> getOrderByColumns()
815     {
816         return orderByColumns;
817     }
818 
819     /**
820      * Get all elements in the from clause of the query.
821      *
822      * @return An UniqueList with all from elements, not null.
823      *         Empty if the from elements should be computed automatically.
824      */
825     public UniqueList<FromElement> getFromElements()
826     {
827         return fromElements;
828     }
829 
830     /**
831      * Adds a table to the from clause, not using a joinType or joinCondition.
832      *
833      * @return the modified Criteria object.
834      */
835     public Criteria addFrom(String tableName)
836     {
837         fromElements.add(new FromElement(tableName));
838         return this;
839     }
840 
841     /**
842      * Adds a new Element to the from clause.
843      *
844      * @return the modified Criteria object.
845      */
846     public Criteria addFrom(FromElement fromElement)
847     {
848         fromElements.add(fromElement);
849         return this;
850     }
851 
852     /**
853      * Build a string representation of the Criteria for debugging purposes.
854      *
855      * @return A String with the representation of the Criteria.
856      */
857     @Override
858     public String toString()
859     {
860         StringBuilder sb = new StringBuilder("Criteria: ");
861         try
862         {
863             Query query = SqlBuilder.buildQuery(this);
864             sb.append("Current Query SQL (may not be complete or applicable): ")
865                     .append(query.getDisplayString());
866         }
867         catch (Exception exc)
868         {
869             sb.append("Error" + exc.getMessage());
870         }
871 
872         return sb.toString();
873     }
874 
875     /**
876      * Checks whether an object is equal to this Criteria.
877      * This is the case if the other object is also a Criteria and has
878      * the same attributes and criterions.
879      *
880      * @param object the other object to check, can be null.
881      *
882      * @return true if the object is equal to this Criteria, false otherwise.
883      */
884     @Override
885     public boolean equals(Object object)
886     {
887         if (object == null)
888         {
889             return false;
890         }
891         if (this == object)
892         {
893             return true;
894         }
895         if (object.getClass() != this.getClass())
896         {
897             return false;
898         }
899         Criteria criteria = (Criteria) object;
900         EqualsBuilder equalsBuilder = new EqualsBuilder();
901         equalsBuilder.append(
902                 criteria.topLevelCriterion,
903                 this.topLevelCriterion);
904         equalsBuilder.append(criteria.offset, this.offset);
905         equalsBuilder.append(criteria.limit, this.limit);
906         equalsBuilder.append(criteria.ignoreCase, this.ignoreCase);
907         equalsBuilder.append(criteria.singleRecord, this.singleRecord);
908         equalsBuilder.append(criteria.dbName, this.dbName);
909         equalsBuilder.append(criteria.selectModifiers, this.selectModifiers);
910         equalsBuilder.append(criteria.selectColumns, this.selectColumns);
911         equalsBuilder.append(criteria.orderByColumns, this.orderByColumns);
912         equalsBuilder.append(criteria.fromElements, this.fromElements);
913         equalsBuilder.append(criteria.aliases, this.aliases);
914         equalsBuilder.append(criteria.asColumns, this.asColumns);
915         equalsBuilder.append(criteria.joins, this.joins);
916         equalsBuilder.append(criteria.fetchSize, this.fetchSize);
917         return equalsBuilder.isEquals();
918     }
919 
920     /**
921      * Returns the hash code value for this Criteria.
922      *
923      * @return a hash code value for this object.
924      */
925     @Override
926     public int hashCode()
927     {
928         HashCodeBuilder hashCodeBuilder = new HashCodeBuilder();
929         hashCodeBuilder.append(topLevelCriterion);
930         hashCodeBuilder.append(offset);
931         hashCodeBuilder.append(limit);
932         hashCodeBuilder.append(ignoreCase);
933         hashCodeBuilder.append(singleRecord);
934         hashCodeBuilder.append(dbName);
935         hashCodeBuilder.append(selectModifiers);
936         hashCodeBuilder.append(selectColumns);
937         hashCodeBuilder.append(orderByColumns);
938         hashCodeBuilder.append(fromElements);
939         hashCodeBuilder.append(aliases);
940         hashCodeBuilder.append(asColumns);
941         hashCodeBuilder.append(joins);
942         hashCodeBuilder.append(fetchSize);
943         return hashCodeBuilder.toHashCode();
944     }
945 
946     /**
947      * Returns a cloned object.
948      */
949     @Override
950     public Object clone()
951     {
952         try
953         {
954             return super.clone();
955         }
956         catch (CloneNotSupportedException e)
957         {
958             // should not happen as we implement Cloneable
959             throw new RuntimeException(e);
960         }
961     }
962 
963     /*
964      * ------------------------------------------------------------------------
965      *
966      * Start of the "and" methods
967      *
968      * ------------------------------------------------------------------------
969      */
970 
971     /**
972      * "AND"s Criterion object with the conditions in this Criteria.
973      * This is used as follows:
974      * <p>
975      * <code>
976      * Criteria crit = new Criteria();
977      * Criterion c = new Criterion(XXXPeer.ID, new Integer(5),
978      *         Criteria.LESS_THAN);
979      * crit.and(c);
980      * </code>
981      *
982      * @param criterion A Criterion object.
983      *
984      * @return A modified Criteria object.
985      */
986     public Criteria and(Criterion criterion)
987     {
988         if (topLevelCriterion == null)
989         {
990             topLevelCriterion = criterion;
991         }
992         else
993         {
994             topLevelCriterion.and(criterion);
995         }
996         return this;
997     }
998 
999     /**
1000      * "AND"s a new condition with the conditions in this Criteria.
1001      * Depending on rValue, the condition is constructed differently:
1002      * Either rValue is a unary comparison operator (i.e. is a SqlEnum and
1003      * getNumberOfCompareOperands() == 1) (e.g. Criteria.ISNULL),
1004      * then lValue is taken as single operand of the operator
1005      * ant the passed operator is used for comparison.
1006      * Otherwise, an EQUAL comparison is used for comparing rValue and lValue.
1007      *
1008      * @param lValue The left hand side of the comparison, not null.
1009      *        If this object implements the Column interface, it is interpreted
1010      *        as a (pseudo)column.
1011      *        If this object is c Criteria, it is interpreted as a subselect.
1012      *        In all other cases, (e.g. string object), it is interpreted as
1013      *        literal value.
1014      * @param rValue The right hand side of the comparison, may be null.
1015      *        If this object is a unary comparison operator, it is taken as
1016      *        comparison operator of the condition to add.
1017      *        If this object implements the Column interface, it is interpreted
1018      *        as a (pseudo)column.
1019      *        If this object is c Criteria, it is interpreted as a subselect.
1020      *        In all other cases, (e.g. string object), it is interpreted as
1021      *        literal value.
1022      *
1023      * @return A modified Criteria object.
1024      */
1025     public Criteria and(Object lValue, Object rValue)
1026     {
1027         if (rValue instanceof SqlEnum)
1028         {
1029             SqlEnum sqlEnum = (SqlEnum) rValue;
1030             if (sqlEnum.getNumberOfCompareOperands() == 1)
1031             {
1032                 return and(lValue, null, sqlEnum);
1033             }
1034         }
1035         return and(lValue, rValue, EQUAL);
1036     }
1037 
1038     /**
1039      * "AND"s a new condition with the conditions in this Criteria.
1040      *
1041      * @param lValue The left hand side of the comparison, not null.
1042      *        If this object implements the Column interface, it is interpreted
1043      *        as a (pseudo)column.
1044      *        If this object is c Criteria, it is interpreted as a subselect.
1045      *        In all other cases, (e.G. string object), it is interpreted as
1046      *        literal value.
1047      * @param rValue The right hand side of the comparison, may be null.
1048      *        If this object implements the Column interface, it is interpreted
1049      *        as a (pseudo)column.
1050      *        If this object is c Criteria, it is interpreted as a subselect.
1051      *        In all other cases, (e.G. string object), it is interpreted as
1052      *        literal value.
1053      * @param comparison the comparison, or <code>Criteria.CUSTOM</code>
1054      *        to specify the expression manually in the rValue parameter.
1055      *
1056      * @return A modified Criteria object.
1057      */
1058     @SuppressWarnings("deprecation")
1059     public Criteria and(Object lValue, Object rValue, SqlEnum comparison)
1060     {
1061         Criterion newCriterion;
1062         if (comparison == SqlEnum.CUSTOM)
1063         {
1064             newCriterion = new Criterion(
1065                     lValue,
1066                     null,
1067                     null,
1068                     (String) rValue,
1069                     null);
1070         }
1071         else
1072         {
1073             newCriterion = new Criterion(lValue, rValue, comparison);
1074         }
1075         if (topLevelCriterion == null)
1076         {
1077             topLevelCriterion = newCriterion;
1078         }
1079         else
1080         {
1081             topLevelCriterion.and(newCriterion);
1082         }
1083         return this;
1084     }
1085 
1086     /**
1087      * Convenience method to AND a new date comparison with the conditions
1088      * in this Criteria. Equal to
1089      * <p>
1090      * <code>
1091      * and(column, new GregorianCalendar(year, month,date), EQUAL);
1092      * </code>
1093      *
1094      * @param lValue The left hand side of the comparison, not null.
1095      *        If this object implements the Column interface, it is interpreted
1096      *        as a (pseudo)column.
1097      *        If this object is c Criteria, it is interpreted as a subselect.
1098      *        In all other cases, (e.G. string object), it is interpreted as
1099      *        literal value.
1100      * @param year The year to compare to.
1101      * @param month The month to compare to.
1102      * @param day The day to compare to.
1103      *
1104      * @return A modified Criteria object.
1105      */
1106     public Criteria andDate(Object lValue, int year, int month, int day)
1107     {
1108         return and(lValue,
1109                 new GregorianCalendar(year, month, day).getTime(),
1110                 Criteria.EQUAL);
1111     }
1112 
1113     /**
1114      * Convenience method to AND a new date comparison with the conditions
1115      * in this Criteria. Equal to
1116      * <p>
1117      * <code>
1118      * and(column, new GregorianCalendar(year, month,date), comparison);
1119      * </code>
1120      *
1121      * @param lValue The left hand side of the comparison, not null.
1122      *        If this object implements the Column interface, it is interpreted
1123      *        as a (pseudo)column.
1124      *        If this object is c Criteria, it is interpreted as a subselect.
1125      *        In all other cases, (e.G. string object), it is interpreted as
1126      *        literal value.
1127      * @param year The year to compare to.
1128      * @param month The month to compare to.
1129      * @param day The day to compare to.
1130      * @param comparison The comparison operator.
1131      *
1132      * @return A modified Criteria object.
1133      */
1134     public Criteria andDate(Object lValue, int year, int month, int day,
1135             SqlEnum comparison)
1136     {
1137         return and(lValue,
1138                 new GregorianCalendar(year, month, day).getTime(),
1139                 comparison);
1140     }
1141 
1142     /**
1143      * Convenience method to AND a "in" comparison with the conditions
1144      * in this Criteria. Creates the condition
1145      * <p>
1146      * FOO.NAME IN (${values})
1147      * <p>
1148      * where ${values} contains the values to compare against.
1149      *
1150      * @param lValue The left hand side of the comparison, not null.
1151      *        If this object implements the Column interface, it is interpreted
1152      *        as a (pseudo)column.
1153      *        If this object is c Criteria, it is interpreted as a subselect.
1154      *        In all other cases, (e.G. string object), it is interpreted as
1155      *        literal value.
1156      * @param rValues The values to compare against.
1157      *
1158      * @return A modified Criteria object.
1159      */
1160     public Criteria andIn(Object lValue, Object[] rValues)
1161     {
1162         return and(lValue, rValues, Criteria.IN);
1163     }
1164 
1165     /**
1166      * Convenience method to AND a "in" comparison with the conditions
1167      * in this Criteria. Creates the condition
1168      * <p>
1169      * FOO.NAME IN (${values})
1170      * <p>
1171      * where ${values} contains the values to compare against.
1172      *
1173      * @param lValue The left hand side of the comparison, not null.
1174      *        If this object implements the Column interface, it is interpreted
1175      *        as a (pseudo)column.
1176      *        If this object is c Criteria, it is interpreted as a subselect.
1177      *        In all other cases, (e.G. string object), it is interpreted as
1178      *        literal value.
1179      * @param rValues The values to compare against.
1180      *
1181      * @return A modified Criteria object.
1182      */
1183     public Criteria andIn(Object lValue, Collection<?> rValues)
1184     {
1185         return and(lValue, rValues, Criteria.IN);
1186     }
1187 
1188     /**
1189      * Convenience method to AND a "not in" comparison with the conditions
1190      * in this Criteria. Creates the condition
1191      * <p>
1192      * FOO.NAME NOT IN (${values})
1193      * <p>
1194      * where ${values} contains the values to compare against.
1195      *
1196      * @param lValue The left hand side of the comparison, not null.
1197      *        If this object implements the Column interface, it is interpreted
1198      *        as a (pseudo)column.
1199      *        If this object is c Criteria, it is interpreted as a subselect.
1200      *        In all other cases, (e.G. string object), it is interpreted as
1201      *        literal value.
1202      * @param rValues The values to compare against.
1203      *
1204      * @return A modified Criteria object.
1205      */
1206     public Criteria andNotIn(Object lValue, Object[] rValues)
1207     {
1208         return and(lValue, rValues, Criteria.NOT_IN);
1209     }
1210 
1211     /**
1212      * Convenience method to AND a "not in" comparison with the conditions
1213      * in this Criteria. Creates the condition
1214      * <p>
1215      * FOO.NAME NOT IN (${values})
1216      * <p>
1217      * where ${values} contains the values to compare against.
1218      *
1219      * @param lValue The left hand side of the comparison, not null.
1220      *        If this object implements the Column interface, it is interpreted
1221      *        as a (pseudo)column.
1222      *        If this object is c Criteria, it is interpreted as a subselect.
1223      *        In all other cases, (e.G. string object), it is interpreted as
1224      *        literal value.
1225      * @param rValues The values to compare against.
1226      *
1227      * @return A modified Criteria object.
1228      */
1229     public Criteria andNotIn(Object lValue, Collection<?> rValues)
1230     {
1231         return and(lValue, rValues, Criteria.NOT_IN);
1232     }
1233 
1234     /**
1235      * Ands a verbatim sql condition to this Criteria.
1236      * This is used as follows:
1237      * <p>
1238      * <code>
1239      * Criteria criteria = ...;
1240      * criteria.andVerbatimSql("count(foo.x) = ?", new Object[] {0});
1241      * </code>
1242      *
1243      * @param sql the verbatim SQL to use.
1244      * @param replacements the replacements for the "?" placeholders in SQL.
1245      *
1246      * @return the modified Criteria.
1247      */
1248     public Criteria andVerbatimSql(String sql, Object[] replacements)
1249     {
1250         Criterion criterion
1251                 = new Criterion(null, null, null, sql, replacements);
1252         and(criterion);
1253         return this;
1254     }
1255 
1256     /**
1257      * ANDs a verbatim sql condition to this Criteria.
1258      * This is used as follows:
1259      * <p>
1260      * <code>
1261      * Criteria criteria = new Criteria();
1262      * criteria.andVerbatimSql(
1263      *     "count(foo.x) = ?",
1264      *     new Object[] {0},
1265      *     FooPeer.X,
1266      *     null);
1267      * </code>
1268      *
1269      * @param sql the verbatim SQL to use.
1270      * @param replacements the replacements for the "?" placeholders in SQL.
1271      * @param toAddToFromClause1 a column to add to from clause, may be null.
1272      * @param toAddToFromClause2 a column to add to from clause, may be null.
1273      *
1274      * @return the modified Criteria.
1275      */
1276     public Criteria andVerbatimSql(
1277             String sql,
1278             Object[] replacements,
1279             Column toAddToFromClause1,
1280             Column toAddToFromClause2)
1281     {
1282         Criterion criterion = new Criterion(
1283                 toAddToFromClause1,
1284                 toAddToFromClause2,
1285                 null,
1286                 sql,
1287                 replacements);
1288         and(criterion);
1289         return this;
1290     }
1291 
1292     /*
1293      * ------------------------------------------------------------------------
1294      *
1295      * Start of the "or" methods
1296      *
1297      * ------------------------------------------------------------------------
1298      */
1299 
1300     /**
1301      * "OR"s a Criterion object with the conditions in this Criteria.
1302      * This is used as follows:
1303      * <p>
1304      * <code>
1305      * Criteria crit = new Criteria();
1306      * Criterion c = new Criterion(XXXPeer.ID, new Integer(5),
1307      *         Criteria.LESS_THAN);
1308      * crit.or(c);
1309      * </code>
1310      *
1311      * @param criterion A Criterion object.
1312      *
1313      * @return A modified Criteria object.
1314      */
1315     public Criteria or(Criterion criterion)
1316     {
1317         if (topLevelCriterion == null)
1318         {
1319             topLevelCriterion = criterion;
1320         }
1321         else
1322         {
1323             topLevelCriterion.or(criterion);
1324         }
1325         return this;
1326     }
1327 
1328     /**
1329      * "OR"s a new condition with the conditions in this Criteria.
1330      * Depending on rValue, the condition is constructed differently:
1331      * Either rValue is a unary comparison operator (i.e. is a SqlEnum and
1332      * getNumberOfCompareOperands() == 1) (e.g. Criteria.ISNULL),
1333      * then lValue is taken as single operand of the operator
1334      * ant the passed operator is used for comparison.
1335      * Otherwise, an EQUAL comparison is used for comparing rValue and lValue.
1336      *
1337      * @param lValue The left hand side of the comparison, not null.
1338      *        If this object implements the Column interface, it is interpreted
1339      *        as a (pseudo)column.
1340      *        If this object is c Criteria, it is interpreted as a subselect.
1341      *        In all other cases, (e.g. string object), it is interpreted as
1342      *        literal value.
1343      * @param rValue The right hand side of the comparison, may be null.
1344      *        If this object is a unary comparison operator, it is taken as
1345      *        comparison operator of the condition to add.
1346      *        If this object implements the Column interface, it is interpreted
1347      *        as a (pseudo)column.
1348      *        If this object is c Criteria, it is interpreted as a subselect.
1349      *        In all other cases, (e.g. string object), it is interpreted as
1350      *        literal value.
1351      *
1352      * @return A modified Criteria object.
1353      */
1354     public Criteria or(Object lValue, Object rValue)
1355     {
1356         if (rValue instanceof SqlEnum)
1357         {
1358             SqlEnum sqlEnum = (SqlEnum) rValue;
1359             if (sqlEnum.getNumberOfCompareOperands() == 1)
1360             {
1361                 return or(lValue, null, sqlEnum);
1362             }
1363         }
1364         return or(lValue, rValue, EQUAL);
1365     }
1366 
1367     /**
1368      * "OR"s a new condition with the conditions in this Criteria.
1369      *
1370      * @param lValue The left hand side of the comparison, not null.
1371      *        If this object implements the Column interface, it is interpreted
1372      *        as a (pseudo)column.
1373      *        If this object is c Criteria, it is interpreted as a subselect.
1374      *        In all other cases, (e.G. string object), it is interpreted as
1375      *        literal value.
1376      * @param rValue The right hand side of the comparison, may be null.
1377      *        If this object implements the Column interface, it is interpreted
1378      *        as a (pseudo)column.
1379      *        If this object is c Criteria, it is interpreted as a subselect.
1380      *        In all other cases, (e.G. string object), it is interpreted as
1381      *        literal value.
1382      * @param comparison the comparison, or <code>Criteria.CUSTOM</code>
1383      *        to specify the expression manually in the value parameter.
1384      *
1385      * @return A modified Criteria object.
1386      */
1387     @SuppressWarnings("deprecation")
1388     public Criteria or(Object lValue, Object rValue, SqlEnum comparison)
1389     {
1390         Criterion newCriterion;
1391         if (comparison == SqlEnum.CUSTOM)
1392         {
1393             newCriterion = new Criterion(
1394                     lValue,
1395                     null,
1396                     null,
1397                     (String) rValue,
1398                     null);
1399         }
1400         else
1401         {
1402             newCriterion = new Criterion(lValue, rValue, comparison);
1403         }
1404         if (topLevelCriterion == null)
1405         {
1406             topLevelCriterion = newCriterion;
1407         }
1408         else
1409         {
1410             topLevelCriterion.or(newCriterion);
1411         }
1412         return this;
1413     }
1414 
1415     /**
1416      * Convenience method to OR a new date comparison with the conditions
1417      * in this Criteria. Equal to
1418      * <p>
1419      * <code>
1420      * or(column, new GregorianCalendar(year, month,date), EQUAL);
1421      * </code>
1422      *
1423      * @param lValue The left hand side of the comparison, not null.
1424      *        If this object implements the Column interface, it is interpreted
1425      *        as a (pseudo)column.
1426      *        If this object is c Criteria, it is interpreted as a subselect.
1427      *        In all other cases, (e.G. string object), it is interpreted as
1428      *        literal value.
1429      * @param year The year to compare to.
1430      * @param month The month to compare to.
1431      * @param day The day to compare to.
1432      *
1433      * @return A modified Criteria object.
1434      */
1435     public Criteria orDate(Object lValue, int year, int month, int day)
1436     {
1437         return or(lValue,
1438                 new GregorianCalendar(year, month, day).getTime(),
1439                 Criteria.EQUAL);
1440     }
1441 
1442     /**
1443      * Convenience method to OR a new date comparison with the conditions
1444      * in this Criteria. Equal to
1445      * <p>
1446      * <code>
1447      * or(column, new GregorianCalendar(year, month,date), comparison);
1448      * </code>
1449      *
1450      * @param lValue The left hand side of the comparison, not null.
1451      *        If this object implements the Column interface, it is interpreted
1452      *        as a (pseudo)column.
1453      *        If this object is c Criteria, it is interpreted as a subselect.
1454      *        In all other cases, (e.G. string object), it is interpreted as
1455      *        literal value.
1456      * @param year The year to compare to.
1457      * @param month The month to compare to.
1458      * @param day The day to compare to.
1459      * @param comparison The comparison operator.
1460      *
1461      * @return A modified Criteria object.
1462      */
1463     public Criteria orDate(Object lValue, int year, int month, int day,
1464             SqlEnum comparison)
1465     {
1466         return or(lValue,
1467                 new GregorianCalendar(year, month, day).getTime(),
1468                 comparison);
1469     }
1470 
1471     /**
1472      * Convenience method to OR a "in" comparison with the conditions
1473      * in this Criteria. Creates the condition
1474      * <p>
1475      * FOO.NAME IN (${values})
1476      * <p>
1477      * where ${values} contains the values to compare against.
1478      *
1479      * @param lValue The left hand side of the comparison, not null.
1480      *        If this object implements the Column interface, it is interpreted
1481      *        as a (pseudo)column.
1482      *        If this object is c Criteria, it is interpreted as a subselect.
1483      *        In all other cases, (e.G. string object), it is interpreted as
1484      *        literal value.
1485      * @param rValues The values to compare against.
1486      *
1487      * @return A modified Criteria object.
1488      */
1489     public Criteria orIn(Object lValue, Object[] rValues)
1490     {
1491         return or(lValue, rValues, Criteria.IN);
1492     }
1493 
1494     /**
1495      * Convenience method to OR a "in" comparison with the conditions
1496      * in this Criteria. Creates the condition
1497      * <p>
1498      * FOO.NAME IN (${values})
1499      * <p>
1500      * where ${values} contains the values to compare against.
1501      *
1502      * @param lValue The left hand side of the comparison, not null.
1503      *        If this object implements the Column interface, it is interpreted
1504      *        as a (pseudo)column.
1505      *        If this object is c Criteria, it is interpreted as a subselect.
1506      *        In all other cases, (e.G. string object), it is interpreted as
1507      *        literal value.
1508      * @param rValues The values to compare against.
1509      *
1510      * @return A modified Criteria object.
1511      */
1512     public Criteria orIn(Object lValue, Collection<?> rValues)
1513     {
1514         return or(lValue, rValues, Criteria.IN);
1515     }
1516 
1517     /**
1518      * Convenience method to OR a "not in" comparison with the conditions
1519      * in this Criteria. Creates the condition
1520      * <p>
1521      * FOO.NAME NOT IN (${values})
1522      * <p>
1523      * where ${values} contains the values to compare against.
1524      *
1525      * @param lValue The left hand side of the comparison, not null.
1526      *        If this object implements the Column interface, it is interpreted
1527      *        as a (pseudo)column.
1528      *        If this object is c Criteria, it is interpreted as a subselect.
1529      *        In all other cases, (e.G. string object), it is interpreted as
1530      *        literal value.
1531      * @param rValues The values to compare against.
1532      *
1533      * @return A modified Criteria object.
1534      */
1535     public Criteria orNotIn(Object lValue, Object[] rValues)
1536     {
1537         return or(lValue, rValues, Criteria.NOT_IN);
1538     }
1539 
1540     /**
1541      * Convenience method to OR a "not in" comparison with the conditions
1542      * in this Criteria. Creates the condition
1543      * <p>
1544      * FOO.NAME NOT IN (${values})
1545      * <p>
1546      * where ${values} contains the values to compare against.
1547      *
1548      * @param lValue The left hand side of the comparison, not null.
1549      *        If this object implements the Column interface, it is interpreted
1550      *        as a (pseudo)column.
1551      *        If this object is c Criteria, it is interpreted as a subselect.
1552      *        In all other cases, (e.G. string object), it is interpreted as
1553      *        literal value.
1554      * @param rValues The values to compare against.
1555      *
1556      * @return A modified Criteria object.
1557      */
1558     public Criteria orNotIn(Object lValue, Collection<?> rValues)
1559     {
1560         return or(lValue, rValues, Criteria.NOT_IN);
1561     }
1562 
1563     /**
1564      * ORs a verbatim sql condition to this Criteria.
1565      * This is used as follows:
1566      * <p>
1567      * <code>
1568      * Criteria criteria = ...;
1569      * criteria.orVerbatimSql("count(foo.x) = ?", new Object[] {0});
1570      * </code>
1571      *
1572      * @param sql the verbatim SQL to use.
1573      * @param replacements the replacements for the "?" placeholders in SQL.
1574      *
1575      * @return the modified Criteria.
1576      */
1577     public Criteria orVerbatimSql(String sql, Object[] replacements)
1578     {
1579         Criterion criterion
1580                 = new Criterion(null, null, null, sql, replacements);
1581         or(criterion);
1582         return this;
1583     }
1584 
1585     /**
1586      * ORs a verbatim sql condition to this Criteria.
1587      * This is used as follows:
1588      * <p>
1589      * <code>
1590      * Criteria criteria = new Criteria();
1591      * criteria.orVerbatimSql(
1592      *     "count(foo.x) = ?",
1593      *     new Object[] {0},
1594      *     FooPeer.X,
1595      *     null);
1596      * </code>
1597      *
1598      * @param sql the verbatim SQL to use.
1599      * @param replacements the replacements for the "?" placeholders in SQL.
1600      * @param toAddToFromClause1 a column to add to from clause, may be null.
1601      * @param toAddToFromClause2 a column to add to from clause, may be null.
1602      *
1603      * @return the modified Criteria.
1604      */
1605     public Criteria orVerbatimSql(
1606             String sql,
1607             Object[] replacements,
1608             Column toAddToFromClause1,
1609             Column toAddToFromClause2)
1610     {
1611         Criterion criterion = new Criterion(
1612                 toAddToFromClause1,
1613                 toAddToFromClause2,
1614                 null,
1615                 sql,
1616                 replacements);
1617         or(criterion);
1618         return this;
1619     }
1620 
1621     /*
1622      * ------------------------------------------------------------------------
1623      *
1624      * Start of the "where" methods
1625      *
1626      * ------------------------------------------------------------------------
1627      */
1628 
1629     /**
1630      * "AND"s Criterion object with the conditions in this Criteria.
1631      * Equivalent to <code>#and(Criterion)</code> but better to read if this is
1632      * the first condition to be added to the Criteria.
1633      *
1634      * @param criterion A Criterion object.
1635      *
1636      * @return A modified Criteria object.
1637      */
1638     public Criteria where(Criterion criterion)
1639     {
1640         return and(criterion);
1641     }
1642 
1643     /**
1644      * "AND"s a new condition with the conditions in this Criteria.
1645      * Equivalent to <code>#and(Object, Object)</code> but better to read
1646      * if this is the first condition to be added to the Criteria.
1647      * Depending on rValue, the condition is constructed differently:
1648      * Either rValue is a unary comparison operator (i.e. is a SqlEnum and
1649      * getNumberOfCompareOperands() == 1) (e.g. Criteria.ISNULL),
1650      * then lValue is taken as single operand of the operator
1651      * ant the passed operator is used for comparison.
1652      * Otherwise, an EQUAL comparison is used for comparing rValue and lValue.
1653      *
1654      * @param lValue The left hand side of the comparison, not null.
1655      *        If this object implements the Column interface, it is interpreted
1656      *        as a (pseudo)column.
1657      *        If this object is c Criteria, it is interpreted as a subselect.
1658      *        In all other cases, (e.g. string object), it is interpreted as
1659      *        literal value.
1660      * @param rValue The right hand side of the comparison, may be null.
1661      *        If this object is a unary comparison operator, it is taken as
1662      *        comparison operator of the condition to add.
1663      *        If this object implements the Column interface, it is interpreted
1664      *        as a (pseudo)column.
1665      *        If this object is c Criteria, it is interpreted as a subselect.
1666      *        In all other cases, (e.g. string object), it is interpreted as
1667      *        literal value.
1668      *
1669      * @return A modified Criteria object.
1670      */
1671     public Criteria where(Object lValue, Object rValue)
1672     {
1673         return and(lValue, rValue);
1674     }
1675 
1676     /**
1677      * "AND"s a new condition with the conditions in this Criteria.
1678      * Equivalent to <code>#and(Column, Object, SqlEnum)</code> but better to
1679      * read if this is the first condition to be added to the Criteria.
1680      *
1681      * @param lValue The left hand side of the comparison, not null.
1682      *        If this object implements the Column interface, it is interpreted
1683      *        as a (pseudo)column.
1684      *        If this object is c Criteria, it is interpreted as a subselect.
1685      *        In all other cases, (e.G. string object), it is interpreted as
1686      *        literal value.
1687      * @param rValue The right hand side of the comparison, may be null.
1688      *        If this object implements the Column interface, it is interpreted
1689      *        as a (pseudo)column.
1690      *        If this object is c Criteria, it is interpreted as a subselect.
1691      *        In all other cases, (e.G. string object), it is interpreted as
1692      *        literal value.
1693      * @param comparison the comparison, or <code>Criteria.CUSTOM</code>
1694      *        to specify the expression manually in the value parameter.
1695      *
1696      * @return A modified Criteria object.
1697      */
1698     public Criteria where(Object lValue, Object rValue, SqlEnum comparison)
1699     {
1700         return and(lValue, rValue, comparison);
1701     }
1702 
1703     /**
1704      * Convenience method to AND a new date comparison with the conditions
1705      * in this Criteria. Equivalent to
1706      * <code>#andDate(Column, int, int, int)</code> but better to read
1707      * if this is the first condition to be added to the Criteria.
1708      *
1709      * @param lValue The left hand side of the comparison, not null.
1710      *        If this object implements the Column interface, it is interpreted
1711      *        as a (pseudo)column.
1712      *        If this object is c Criteria, it is interpreted as a subselect.
1713      *        In all other cases, (e.G. string object), it is interpreted as
1714      *        literal value.
1715      * @param year The year to compare to.
1716      * @param month The month to compare to.
1717      * @param day The day to compare to.
1718      *
1719      * @return A modified Criteria object.
1720      */
1721     public Criteria whereDate(Object lValue, int year, int month, int day)
1722     {
1723         return andDate(lValue, year, month, day);
1724     }
1725 
1726     /**
1727      * Convenience method to AND a new date comparison with the conditions
1728      * in this Criteria. Equivalent to
1729      * <code>#andDate(Column, int, int, int, SqlEnum)</code> but better to read
1730      * if this is the first condition to be added to the Criteria.
1731      *
1732      * @param lValue The left hand side of the comparison, not null.
1733      *        If this object implements the Column interface, it is interpreted
1734      *        as a (pseudo)column.
1735      *        If this object is c Criteria, it is interpreted as a subselect.
1736      *        In all other cases, (e.G. string object), it is interpreted as
1737      *        literal value.
1738      * @param year The year to compare to.
1739      * @param month The month to compare to.
1740      * @param day The day to compare to.
1741      * @param comparison The comparison operator.
1742      *
1743      * @return A modified Criteria object.
1744      */
1745     public Criteria whereDate(Object lValue, int year, int month, int day,
1746             SqlEnum comparison)
1747     {
1748         return andDate(lValue, year, month, day, comparison);
1749     }
1750 
1751     /**
1752      * Convenience method to AND a "in" comparison with the conditions
1753      * in this Criteria. Equivalent to <code>#andIn(Column, Object[])</code>
1754      * but better to read if this is the first condition to be added
1755      * to the Criteria.
1756      *
1757      * @param lValue The left hand side of the comparison, not null.
1758      *        If this object implements the Column interface, it is interpreted
1759      *        as a (pseudo)column.
1760      *        If this object is c Criteria, it is interpreted as a subselect.
1761      *        In all other cases, (e.G. string object), it is interpreted as
1762      *        literal value.
1763      * @param rValues The values to compare against.
1764      *
1765      * @return A modified Criteria object.
1766      */
1767     public Criteria whereIn(Object lValue, Object[] rValues)
1768     {
1769         return andIn(lValue, rValues);
1770     }
1771 
1772     /**
1773      * Convenience method to AND a "in" comparison with the conditions
1774      * in this Criteria. Equivalent to <code>#andIn(Column, Collection)</code>
1775      * but better to read if this is the first condition to be added
1776      * to the Criteria.
1777      *
1778      * @param lValue The left hand side of the comparison, not null.
1779      *        If this object implements the Column interface, it is interpreted
1780      *        as a (pseudo)column.
1781      *        If this object is c Criteria, it is interpreted as a subselect.
1782      *        In all other cases, (e.G. string object), it is interpreted as
1783      *        literal value.
1784      * @param rValues The values to compare against.
1785      *
1786      * @return A modified Criteria object.
1787      */
1788     public Criteria whereIn(Object lValue, Collection<?> rValues)
1789     {
1790         return andIn(lValue, rValues);
1791     }
1792 
1793     /**
1794      * Convenience method to AND a "not in" comparison with the conditions
1795      * in this Criteria. Equivalent to
1796      * <code>#andNotIn(Column, Object[])</code> but better to read
1797      * if this is the first condition to be added to the Criteria.
1798      *
1799      * @param lValue The left hand side of the comparison, not null.
1800      *        If this object implements the Column interface, it is interpreted
1801      *        as a (pseudo)column.
1802      *        If this object is c Criteria, it is interpreted as a subselect.
1803      *        In all other cases, (e.G. string object), it is interpreted as
1804      *        literal value.
1805      * @param rValues The values to compare against.
1806      *
1807      * @return A modified Criteria object.
1808      */
1809     public Criteria whereNotIn(Object lValue, Object[] rValues)
1810     {
1811         return andNotIn(lValue, rValues);
1812     }
1813 
1814     /**
1815      * Convenience method to AND a "not in" comparison with the conditions
1816      * in this Criteria. Equivalent to
1817      * <code>#andNotIn(Column, Collection)</code> but better to read
1818      * if this is the first condition to be added to the Criteria.
1819      *
1820      * @param lValue The left hand side of the comparison, not null.
1821      *        If this object implements the Column interface, it is interpreted
1822      *        as a (pseudo)column.
1823      *        If this object is c Criteria, it is interpreted as a subselect.
1824      *        In all other cases, (e.G. string object), it is interpreted as
1825      *        literal value.
1826      * @param rValues The values to compare against.
1827      * @return A modified Criteria object.
1828      */
1829     public Criteria whereNotIn(Object lValue, Collection<?> rValues)
1830     {
1831         return andNotIn(lValue, rValues);
1832     }
1833 
1834     /**
1835      * Convenience method to AND a verbatim sql condition to this Criteria.
1836      * Equivalent to
1837      * <code>#andNotIn(String, String[])</code> but better to read
1838      * if this is the first condition to be added to the Criteria.
1839      * This is used as follows:
1840      * <p>
1841      * <code>
1842      * Criteria criteria = new Criteria();
1843      * criteria.whereVerbatimSql("count(foo.x) = ?", new Object[] {0});
1844      * </code>
1845      *
1846      * @param sql the verbatim SQL to use.
1847      * @param replacements the replacements for the "?" placeholders in SQL.
1848      *
1849      * @return the modified Criteria.
1850      */
1851     public Criteria whereVerbatimSql(String sql, Object[] replacements)
1852     {
1853         Criterion criterion
1854                 = new Criterion(null, null, null, sql, replacements);
1855         and(criterion);
1856         return this;
1857     }
1858 
1859     /**
1860      * Convenience method to AND a verbatim sql condition to this Criteria.
1861      * Equivalent to
1862      * <code>#andNotIn(String, String[], Column, Column)</code> but better
1863      * to read if this is the first condition to be added to the Criteria.
1864      * This is used as follows:
1865      * <p>
1866      * <code>
1867      * Criteria criteria = new Criteria();
1868      * criteria.whereVerbatimSql(
1869      *     "count(foo.x) = ?",
1870      *     new Object[] {0},
1871      *     FooPeer.X,
1872      *     null);
1873      * </code>
1874      *
1875      * @param sql the verbatim SQL to use.
1876      * @param replacements the replacements for the "?" placeholders in SQL.
1877      * @param toAddToFromClause1 a column to add to from clause, may be null.
1878      * @param toAddToFromClause2 a column to add to from clause, may be null.
1879      *
1880      * @return the modified Criteria.
1881      */
1882     public Criteria whereVerbatimSql(
1883             String sql,
1884             Object[] replacements,
1885             Column toAddToFromClause1,
1886             Column toAddToFromClause2)
1887     {
1888         Criterion criterion = new Criterion(
1889                 toAddToFromClause1,
1890                 toAddToFromClause2,
1891                 null,
1892                 sql,
1893                 replacements);
1894         and(criterion);
1895         return this;
1896     }
1897 }