Class Generate

  extended by fc.jdbc.dbo.Generate

public final class Generate
extends java.lang.Object

Generates java objects that represent tables in a database. Each object represents 1 table in the database.

This framework is great for inserting and updating data in various tables and even fetching one or more rows form individual tables.

For each table foo in our database, the following classes are generated:

  1. class Foo which contains all columns of table foo as fields and represents a row in that table. Accessor (get/set) methods are provided to modify the values of fields in this class (Note, all generated fields are themselves declared private and we always go through accessor methods so we can keep track of various modifications etc.)
  2. class FooMgr which contains "manager" type functions to read, save, create, etc., instances of class Foo from/to the database. The methods of FooMgr could equivalently have been implemented as static methods in Foo but they have been separated out in a separate manager class to reduce clutter.

    This framework is not intended to transparently allow arbitrary joins and data from multiple tables. A better way is to use prepared statements directly to run ad-hoc SQL queries including those containing arbitrary joins.

    However, to somewhat facilitate arbitrary select queries/joins across multiple tables, each generated "Mgr" class has a columns() method that returns a list of columns for the corresponding table. For example, in say a Molly Server Page where information from two tables (table1, table2) is displayed from both tables on the same page.

    String my_query =  "select "
      + table1Mgr.columns() + ", " + table2.columns()
      + " from table1, table2 WHERE table1.x = table2.x";
    PreparedStatement ps = connection.prepareStatement(my_query);
    ResultSet rs = connection.executeQuery();
    while (rs.next())
        table1 t1 = table1Mgr.getFromRS(rs);  //create a new table1 from the rs
        table2 t2 = table2Mgr.getFromRS(rs);  //ditto for table2
        //..use t1 and t2...


This program uses a user specified configuration file that allows for many code generation options. This file takes the following configuration options

Here is a minimal sample configuration file.


Note 1: This framework always retrieves and saves data directly to and fro from the database and never caches data internally. This is a design feature and keeps this framework orthogonal to caching issues/implementations. The results returned by the framework can always be cached as needed via say, the Cache utility class(es).

Note 2: MySQL 3.x, 4.x or 5.x does not have true boolean types and silently converts bool types to TINYINT. This wreaks havoc with auto-generated code which creates methods with the wrong signature (TINYINT as opposed to bool).

There are 2 approaches to solving this mysql-specific problem:

a) Require all boolean columns to begin with some keyword (say bool_) and if a column begins with this word, then treat it as a boolean, regardless of the type returned by the database meta data.

b) Treat all TINYINT's as boolean types. This is the approach I have chosen since TINYINT's are NOT portable across databases (for example PostgresQL does not have TINYINT's). Therefore we should not use TINYINT's in physical database models; if booleans are turned into TINYINT's by MySQL then so be it..since that will not clash with any of our modelled types.
If the flag mysqlBooleanHack is set to false in the configuration file, then TINYINT's are not transformed to booleans. There should be no practical need to do this however.

Note 3: MySQL allows its tables and columns to start with a numeral. For example: 52_weeks, 3_col, etc. This is wrong, not-standard and not-supported. From the spec:

SQL identifiers and key words must begin with a letter (a-z, but also letters with diacritical marks and non-Latin letters) or an underscore (_). Subsequent characters in an identifier or key word can be letters, underscores, digits (0-9), or dollar signs ($).

So compiling these wrongly named tables (which only MySQL and no other database allows) results in a bunch of java compiler errors, which may confuse neophytes into believing that the generator is outputting buggy code. No, the generated code is proper and exactly the way its intended to be. Java variables/classes cannot start with a number. Hence, compiler errors. So if you must use MySQL, at least don't name your tables with a number.

Constructor Summary
Generate(java.lang.String[] args)
Method Summary
static void main(java.lang.String[] args)
          Usage: java fc.jdbc.dbobjects.Generate -conf No flags will produce a list of options and usage information.
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructor Detail


public Generate(java.lang.String[] args)
         throws java.lang.Exception
Method Detail


public static void main(java.lang.String[] args)
                 throws java.lang.Exception
Usage: java fc.jdbc.dbobjects.Generate -conf No flags will produce a list of options and usage information.