Author: jgbutler
Date: Wed Feb  6 15:41:44 2008
New Revision: 619222

URL: http://svn.apache.org/viewvc?rev=619222&view=rev
Log:
Abator: changes to make the example classes easier to extend, and documentation 
for extending them

Added:
    
ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/generatedobjects/extendingExampleClass.html
Modified:
    ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/version.properties
    ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/menu.html
    ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/whatsNew.html
    
ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/java/model/JavaModelGeneratorJava2Impl.java
    
ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/java/model/JavaModelGeneratorJava5Impl.java

Modified: 
ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/version.properties
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/version.properties?rev=619222&r1=619221&r2=619222&view=diff
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/version.properties 
(original)
+++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/build/version.properties 
Wed Feb  6 15:41:44 2008
@@ -1,4 +1,4 @@
 #Abator build version info
-#Tue Feb 05 12:11:25 CST 2008
+#Tue Feb 05 19:43:36 CST 2008
 version=1.1.0
-buildNum=402
+buildNum=403

Added: 
ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/generatedobjects/extendingExampleClass.html
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/generatedobjects/extendingExampleClass.html?rev=619222&view=auto
==============================================================================
--- 
ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/generatedobjects/extendingExampleClass.html
 (added)
+++ 
ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/generatedobjects/extendingExampleClass.html
 Wed Feb  6 15:41:44 2008
@@ -0,0 +1,226 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";>
+
+<html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en" lang="en">
+<head>
+  <title>Extending the Example Classes</title>
+  <link type="text/css" rel="stylesheet" href="../abator.css"/>
+</head>
+<body>
+<h1>Extending the Example Classes</h1>
+<p><b>Important:</b> the information on this page only applies to classes
+generated with the Java2 or Java5 generator sets.</p>
+<p>In some cases it may be desirable to extended the generated example classes.
+You may want to add criterion that are specific to your database (such as 
Oracle
+ROWNUM support), or add criterion that are not automatically generated (such as
+a case insensitive search).  In situations like these, you may extend the 
generated
+example class to add these additional criteria.</p>
+
+<h2>General Principles</h2>
+<p>Abator generates an "example" class for each table, unless instructed 
otherwise
+in the configuration.  The "example" class is used to generate a dynamic where
+clause for use in the
+<code>selectByExample</code>, <code>deleteByExample</code>,
+<code>updateByExample</code>, and <code>countByExample</code> statements.
+The standard "example" class includes functionality for all standard SQL 
predicates.
+In some cases, it may be desirable to add additional predicates for the
+specific needs of your application.  This may include adding support for 
non-standard
+predicates, or for using database specific functions in your where clauses.</p>
+
+<p>The generated "example" class includes a nested inner class where the actual
+functionality of the predicates exists.  This inner class is always named 
<code>Criteria</code>.
+If you wish to add predicates to dynamic where clauses, you must extend
+both the "example" class and the <code>Criteria</code> class.  For example, 
suppose there is a
+table called CUSTOMER.  Typically, Abator would generate a class named
+<code>CustomerExample</code>.  To add functionality to the 
<code>CustomerExample</code> class, you must
+follow these steps:</p>
+<ul>
+  <li>Extend the <code>CustomerExample</code> class</li>
+  <li>Extend the nested <code>CustomerExample$Criteria</code> class</li>
+  <li>Override the <code>createCriteriaInternal()</code> method of the
+      <code>CustomerExample</code> class so that the extended Criteria
+      class is created</li>
+  <li>Add functionality to the extended Criteria class</li>
+</ul>
+
+<p>The following code fragment shows the basic requirements of an extended
+example class:</p>
+<pre>
+import abatortest.generated.CustomerExample;
+
+public class ExtendedCustomerExample extends CustomerExample {
+
+  @Override
+  protected Criteria createCriteriaInternal() {
+    return new ExtendedCriteria();
+  }
+
+  public static class ExtendedCriteria extends CustomerExample.Criteria {
+
+    // add additional predicate support here...
+
+  }
+}
+</pre>
+
+<p>Once the basic class is created, adding additional predicates is a matter
+of adding additional methods the the extended <code>Criteria</code> class.</p>
+
+<h2>Adding Predicates</h2>
+<p>Abator generates a dynamic SQL fragment that allows virtually unlimited
+where clauses to be created at run-time.  To accomplish this, the generated SQL
+fragment supports four broad types of SQL predicates.  For each type of
+SQL predicate, there is a corresponding method in the generated 
<code>Criteria</code> class
+that can be used to add a predicate to the dynamic where clause.</p>
+
+<h3>1. Simple String Substitution</h3>
+<p>This type of predicate is used when there is no need for a property
+from the parameter object to be substituted into the where clause.  Examples
+include:</p>
+<p><code>FIRST_NAME is null</code><br/>
+   <code>LAST_NAME is not null</code></p>
+
+<p>The generated <code>Criteria</code> class method for this predicate is:</p>
+&nbsp;&nbsp;&nbsp;<code>addCriterion(String anyString)</code>
+
+<p>Where "anyString" is the string to be substituted into the where clauses.
+This method can be used to add any kind of test to the generated where 
clause.</p>
+
+<p>For example, suppose you wanted to use the SOUNDEX function to do a "sounds 
like"
+name search.  In MySQL, the predicate should look like this:</p>
+<code>SOUNDEX(FIRST_NAME) = SOUNDEX('frod')</code>
+<p>This predicate is too complex to use one of the other methods, so it must
+be inserted into the where clause by simple string substitition.  Add the 
following
+method to the <code>ExtendedCriteria</code> for this functionality:</p>
+<pre>
+public ExtendedCriteria andFirstNameSoundsLike(String value) {
+  StringBuffer sb = new StringBuffer("SOUNDEX(FIRST_NAME) = SOUNDEX('");
+  sb.append(value);
+  sb.append("')");
+
+  addCriterion(sb.toString());
+
+  return this;
+}
+</pre>
+
+<p>The following code shows the use of this new functionality with the 
<code>selectByExample</code> method:</p>
+<pre>
+ExtendedExample example = new ExtendedExample();
+ExtendedCriteria criteria = (ExtendedCriteria) example.createCriteria();
+criteria.andFirstNameSoundsLike("frod");
+List results = selectByExample(example);
+</pre>
+
+<p>This method can be used to add virtually any predicate to a where clause.
+However, it is generally better to use parameter substitution if possible 
because
+the problems of formatting different datatypes properly (most notably
+dates, times, and timestamps).  Also, there is a chance of SQL
+injection issues with this method if you expose a too generic method.
+If at all possible, we suggest using one of the other methods listed below.</p>
+
+<h3>2. Single Parameter Predicates</h3>
+<p>This type of predicate is used when there is a single property
+   from the parameter object to be substituted into the where clause.  Examples
+   include</p>
+<p><code>FIRST_NAME = ?</code><br/>
+   <code>LAST_NAME &lt;&gt; ?</code></p>
+
+<p>The generated <code>Criteria</code> class method for this predicate is:</p>
+<p>&nbsp;&nbsp;&nbsp;<code>addCriterion(String anyString, Object anyObject, 
String propertyName)</code></p>
+
+<p>Where:</p>
+<dl>
+  <dt><b>anyString</b></dt>
+  <dd>is the string to be substituted into the where clause before a parameter 
substitution</dd>
+  <dt><b>anyObject</b></dt>
+  <dd>is the Object to be substituted into the where clause after the string 
substitution</dd>
+  <dt><b>propertyName</b></dt>
+  <dd>is a string denoting the property name related to this clause.  This 
String is only used
+      in potential error messages.</dd>
+</dl>
+
+This method can be used to add simple tests related to a single parameter to 
the generated where clause.</p>
+
+<p>For example, suppose you wanted to select customers who are at least 16 
years old.
+In MySQL, the predicate could look like this:</p>
+<code>DATEDIFF(CURDATE(), BIRTH_DATE) >= 5844</code>
+<p><i>Note: This assumes 365.25 days per year - a crude approximation</i></p>
+<p>This predicate fits the capabilities of a single parameter predicate - 
where the predicate
+is a string value followed by a single parameter.  Add the following
+method to the <code>ExtendedCriteria</code> for this functionality:</p>
+<pre>
+public ExtendedCriteria andAgeGreaterThanOrEqual(int value) {
+  int days = (int) (365.25 * value);
+
+  addCriterion("DATEDIFF(CURDATE(), BIRTH_DATE) >=",
+    new Integer(days), "age");
+
+  return this;
+}
+</pre>
+
+<p>The following code shows the use of this new functionality with the 
<code>selectByExample</code> method:</p>
+<pre>
+ExtendedExample example = new ExtendedExample();
+ExtendedCriteria criteria = (ExtendedCriteria) example.createCriteria();
+criteria.andAgeGreaterThanOrEqual(16);
+List results = selectByExample(example);
+</pre>
+
+<h3>3. List Predicates</h3>
+<p>List predicates are used to add a variable sized list of values as 
parameters to a where
+clause.  Examples include:</p>
+<p><code>FIRST_NAME IN (?, ?, ?)</code><br/>
+<code>LAST_NAME NOT IN (?, ?, ?, ?)</code></p>
+
+<p>This predicate is less flexible then the others because it is included 
specifically
+for the "in" and "not in" standard predicates.  Nevertheless, if you find some 
use for it
+the corresponding method in the <code>Criteria</code> class is as follows:</p>
+
+<p>&nbsp;&nbsp;&nbsp;<code>addCriterion(String anyString, List listOfObjects, 
String propertyName)</code></p>
+
+<p>Where:</p>
+<dl>
+  <dt><b>anyString</b></dt>
+  <dd>is the string to be substituted into the where clause before a parameter 
substitution</dd>
+  <dt><b>listOfObjects</b></dt>
+  <dd>is the List of Objects to be substituted into the where clause after the 
string substitution
+      (an open parenthesis will be appended before the list, list items will 
be comma delimited,
+      and a close parenthesis will be appended after the list).</dd>
+  <dt><b>propertyName</b></dt>
+  <dd>is a string denoting the property name related to this clause.  This 
String is only used
+      in potential error messages.</dd>
+</dl>
+
+<h3>4. Between Predicates</h3>
+<p>Between predicates are used to add a two parameters to a where
+clause in a specific format.  Examples include:</p>
+<p><code>FIRST_NAME BETWEEN ? AND ?</code><br/>
+<code>LAST_NAME NOT BETWEEN ? AND ?</code></p>
+
+<p>This predicate is less flexible then the others because it is included 
specifically
+for the "between" and "not between" standard predicates.  Nevertheless, if you 
find some use for it
+the corresponding method in the <code>Criteria</code> class is as follows:</p>
+
+<p>&nbsp;&nbsp;&nbsp;<code>addCriterion(String anyString, Object object1, 
Object object2, String propertyName)</code></p>
+
+<p>Where:</p>
+<dl>
+  <dt><b>anyString</b></dt>
+  <dd>is the string to be substituted into the where clause before a parameter 
substitution</dd>
+  <dt><b>object1</b></dt>
+  <dd>is the objects to be substituted into the where clause after the string 
substitution
+      (the word "and" will be appended after this object).</dd>
+  <dt><b>object2</b></dt>
+  <dd>is the objects to be substituted into the where clause after the word 
"and".</dd>
+  <dt><b>propertyName</b></dt>
+  <dd>is a string denoting the property name related to this clause.  This 
String is only used
+      in potential error messages.</dd>
+</dl>
+
+
+
+</body>
+</html>

Modified: ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/menu.html
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/menu.html?rev=619222&r1=619221&r2=619222&view=diff
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/menu.html 
(original)
+++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/menu.html Wed 
Feb  6 15:41:44 2008
@@ -38,6 +38,7 @@
   &nbsp;&nbsp;<a href="generatedobjects/sqlmap.html" target="mainFrame">SQL 
Map Files</a><br/>
   &nbsp;&nbsp;<a href="generatedobjects/javadao.html" target="mainFrame">DAO 
Interfaces and Classes</a><br/>
   &nbsp;&nbsp;<a href="generatedobjects/exampleClassUsage.html" 
target="mainFrame">Example Class Usage Notes</a><br/>
+  &nbsp;&nbsp;<a href="generatedobjects/extendingExampleClass.html" 
target="mainFrame">Extending the Example Classes</a><br/>
 
   <a href="usage/intro.html" target="mainFrame">Database Specific 
Information</a><br/>
   &nbsp;&nbsp;<a href="usage/db2.html" target="mainFrame">DB2</a><br/>

Modified: 
ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/whatsNew.html
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/whatsNew.html?rev=619222&r1=619221&r2=619222&view=diff
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/whatsNew.html 
(original)
+++ ibatis/trunk/java/mapper/mapper2/tools/abator/core/htmldoc/whatsNew.html 
Wed Feb  6 15:41:44 2008
@@ -37,8 +37,7 @@
 
 <h3>Miscellaneous Changes</h3>
 <ul>
-  <li>Java2 is now the default generator set.  <b>The Legacy generator set 
will be removed in
-      the next release of Abator.</b></li>
+  <li>Java2 is now the default generator set.</li>
   <li>Added the ability to specify properties to ignore qualifiers and change 
runtime
       table names in the generated SQL for a table.  Primary use cases for this
       support include:
@@ -77,7 +76,10 @@
       </ul>
     See the <a href="configreference/table.html">&lt;table&gt;</a>
     reference page for more information.</li>
-  <li>Made the generated Example and Criteria classes extendable</li>
+  <li>Made the generated Example and Criteria classes extendable.  Added some 
documentation
+      about how to extend these classes.  See the
+      <a href="generatedobjects/extendingExampleClass.html">Extending the 
Example Classes</a>
+      reference page for more information.</li>
   <li>Made the legacy DAOs extendable</li>
   <li>Added the ability to provide a renaming rule for columns.  This is for 
the
       use case where columns have a common prefix that should be removed before

Modified: 
ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/java/model/JavaModelGeneratorJava2Impl.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/java/model/JavaModelGeneratorJava2Impl.java?rev=619222&r1=619221&r2=619222&view=diff
==============================================================================
--- 
ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/java/model/JavaModelGeneratorJava2Impl.java
 (original)
+++ 
ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/java/model/JavaModelGeneratorJava2Impl.java
 Wed Feb  6 15:41:44 2008
@@ -622,7 +622,7 @@
         method.setName(sb.toString());
         method.setReturnType(FullyQualifiedJavaType.getCriteriaInstance());
         sb.setLength(0);
-        sb.append("criteriaWithoutValue.add(\""); //$NON-NLS-1$
+        sb.append("addCriterion(\""); //$NON-NLS-1$
         sb.append(cd.getAliasedActualColumnName());
         sb.append(' ');
         sb.append(operator);
@@ -969,6 +969,21 @@
         answer.addMethod(method);
 
         // now add the methods for simplifying the individual field set methods
+        method = new Method();
+        method.setVisibility(JavaVisibility.PROTECTED);
+        if (abatorContext.getSuppressTypeWarnings()) {
+            method.addSuppressTypeWarningsAnnotation();
+        }
+        method.setName("addCriterion"); //$NON-NLS-1$
+        method.addParameter(new Parameter(FullyQualifiedJavaType
+                .getStringInstance(), "condition")); //$NON-NLS-1$
+        method.addBodyLine("if (condition == null) {"); //$NON-NLS-1$
+        method
+                .addBodyLine("throw new RuntimeException(\"Value for condition 
cannot be null\");"); //$NON-NLS-1$
+        method.addBodyLine("}"); //$NON-NLS-1$
+        method.addBodyLine("criteriaWithoutValue.add(condition);"); 
//$NON-NLS-1$
+        answer.addMethod(method);
+
         method = new Method();
         method.setVisibility(JavaVisibility.PROTECTED);
         if (abatorContext.getSuppressTypeWarnings()) {

Modified: 
ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/java/model/JavaModelGeneratorJava5Impl.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/java/model/JavaModelGeneratorJava5Impl.java?rev=619222&r1=619221&r2=619222&view=diff
==============================================================================
--- 
ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/java/model/JavaModelGeneratorJava5Impl.java
 (original)
+++ 
ibatis/trunk/java/mapper/mapper2/tools/abator/core/src/org/apache/ibatis/abator/internal/java/model/JavaModelGeneratorJava5Impl.java
 Wed Feb  6 15:41:44 2008
@@ -324,6 +324,18 @@
         method.setName("addCriterion"); //$NON-NLS-1$
         method.addParameter(new Parameter(FullyQualifiedJavaType
                 .getStringInstance(), "condition")); //$NON-NLS-1$
+        method.addBodyLine("if (condition == null) {"); //$NON-NLS-1$
+        method
+                .addBodyLine("throw new RuntimeException(\"Value for condition 
cannot be null\");"); //$NON-NLS-1$
+        method.addBodyLine("}"); //$NON-NLS-1$
+        method.addBodyLine("criteriaWithoutValue.add(condition);"); 
//$NON-NLS-1$
+        answer.addMethod(method);
+
+        method = new Method();
+        method.setVisibility(JavaVisibility.PROTECTED);
+        method.setName("addCriterion"); //$NON-NLS-1$
+        method.addParameter(new Parameter(FullyQualifiedJavaType
+                .getStringInstance(), "condition")); //$NON-NLS-1$
         method.addParameter(new Parameter(FullyQualifiedJavaType
                 .getObjectInstance(), "value")); //$NON-NLS-1$
         method.addParameter(new Parameter(FullyQualifiedJavaType


Reply via email to