LAST UPDATED: 2002-06-05 by Geoff Fortytwo (g42@_REMOVE_IF_NOT_SPAM_snowball.com)
Torque is a persistence layer. Torque generates classes which are used by your application to manipulate your DB tables.
In other words, you specify what DB tables you want to have, and it generates classes that you use to interact with those DB tables.
As of 2002-05-27, the latest released version of Torque is called "torque-3.0-b2".
In the following HOWTO, I use an example project called gamerprof (which stands for Gamer Profile) to illustrate how to use Torque. It's a very simple example. It is used simply to save and load information about the game preferences of multiple people (gamers).
To use Torque in a project you need to do the following: 1. Set up the ID Broker (if you want to use it) 2. Create an XML DB schema (for gamerprof it's "gamerprof-schema.xml"). 3. Create a Torque project properties file (for gamerprof it's "gamerprofTorqueBuild.properties"). 4. Modify the project's ANT build file to include the Torque stuff which generates the project Object Model (OM) java files. 5. Create a Torque runtime properties file (for gamerprof it's "Torque.properties"). 6. Make sure that Torque is started before any DB access by putting the following in a static section of a class that'll always be loaded before any of the Torque generated classes are used: org.apache.torque.Torque.init(torquePropPath+"/Torque.properties"); For gamerprof, that line is in a static section of the com.snowball.gamerprof.MainTest class. 7. Add your own methods to the torque generated classes.
In the torque root directory, modify the build.properties so that the value of the "database" property specifies your DB type.
Go to the torque root directory and execute the following command:
ant -buildfile build-torque.xml id-table-init-sql
{TORQUE_ROOT}/src/sql/{DATABASE}-id-table-init.sql
You can use that SQL to create the IDBROKER table which will be used to generate IDs for use as primary keys in your objects.
Here's the schema used by the gamerprof example: gamerprof-schema.xml
The "project" property in the gamerprofTorqueBuild.properties file specifies what the schema xml file will be. So if the value of "project" in that properties file is "gamerprof" then the schema file will be called "gamerprof-schema.xml".
This properties file is referenced in the ANT "gamerprof-om" target of the build.xml file.
<!-- This describes a database table called "Game" which has 3 columns: id, title, tradeInPointWorth --> <table name="Game" javaName="Game" idMethod="none" skipSql="true"> <!-- This column is an INTEGER. That means it is java type "int". It won't be "Integer", so any null values in an "INTEGER" column are returned as zeros (just like they are in JDBC if you call getInt()). --> <column name="id" javaName="Id" required="true" type="INTEGER" size="10"/> <!-- This represents a VARCHAR. That means it is java type "String". --> <column name="title" javaName="Title" required="true" type="VARCHAR" size="200"/> <column name="tradeInPointWorth" javaName="TradeInPointWorth" required="true" type="INTEGER" size="3"/> </table>
Five files will be generated when the ANT target is run:
BaseGame.java This contains the implementations all the accessor functions to this object (like getId(), getTitle(), etc.). This class is replaced every time the Torque ANT target is executed (In this case "ant gamerprof-om"). BaseGamePeer.java This contains the implementations of various constants and static functions that are used to query, update, insert, and delete Game values in the corresponding DB table that the Game.java class represents. This class is replaced every time the Torque ANT target is executed (In this case "ant gamerprof-om"). Game.java This is an empty class that's derived from BaseGame. This class is NOT replaced every time the Torque ANT target is executed (In this case "ant gamerprof-om"). Torque only generates this class if it does not exist already. GamePeer.java This is an empty class that's derived from BaseGamePeer. This class is NOT replaced every time the Torque ANT target is executed (In this case "ant gamerprof-om"). Torque only generates this class if it does not exist already. GameMapBuilder.java I don't really know what this class does. I've never needed to call any functions on it or make any modifications to it. This class is replaced every time the Torque ANT target is executed. (In this case "ant gamerprof-om")
Actually, a feature in Torque would optionally also create a GameManager.java file which would be used for caching. However, that feature is still considered experimental (as of 2002-05-27), so I don't use it.
MainTest.java contains some basic examples of how to use Game and GamePeer.
There's a lot of DB config info in the Torque config files, but the way I use Torque, I don't use the torque connection pool at all. Anytime a db connection is needed (meaning anytime I call a function on any of the generated *Peer classes), I create an instance of a wrapper class around a SimpleConnection. Here's the wrapper class:
See GamePeer.java and Game.java for examples of how I use DBConn.
Until the next version of torque comes out, every time I generate the DB classes I need to do a recursive replace of
"BasePeer.doSelect" to "BasePeer.doPSSelect"
This makes all SELECT statements use prepared statements.
In the xml schema file for torque, any int field that may not contain null values can be of type "INTEGER". That way, the java type used will be "int". However, if you want to be able to retrieve or set null values in an int field then it needs to be type "NUMERIC". Those fields will be represented by the java type "BigDecimal". Hopefully in the next version they'll allow nulls in INTEGER fields.
The following is a list of allowed field types that can be used in the schema.xml file. I got it from the database.dtd file in the Torque distribution:
BIT | TINYINT | SMALLINT | INTEGER | BIGINT | FLOAT | REAL | NUMERIC | DECIMAL | CHAR | VARCHAR | LONGVARCHAR | DATE | TIME | TIMESTAMP | BINARY | VARBINARY | LONGVARBINARY | NULL | OTHER | JAVA_OBJECT | DISTINCT | STRUCT | ARRAY | BLOB | CLOB | REF | BOOLEANINT | BOOLEANCHAR | DOUBLE
I can only describe the following fields because I haven't used any of the others:
Torque type | Java type | NOTES |
---|---|---|
BIT | ||
TINYINT | ||
SMALLINT | ||
INTEGER | int | Nulls become 0. Use Torque type "NUMERIC" if you want to represent null. |
BIGINT | ||
FLOAT | ||
REAL | ||
NUMERIC | java.math.BigDecimal | (This may do exactly what torque type DECIMAL does, but I haven't tried it with a none integer size parameter in the schema, so I don't know.) |
DECIMAL | java.math.BigDecimal | With DECIMAL, using size="5,2" in the schema means it'll represent a NUMBER(5,2) in Oracle. |
CHAR | ||
VARCHAR | String | |
LONGVARCHAR | ||
DATE | java.sql.Date | |
TIME | ||
TIMESTAMP | ||
BINARY | ||
VARBINARY | ||
LONGVARBINARY | ||
NULL | ||
OTHER | ||
JAVA_OBJECT | ||
DISTINCT | ||
STRUCT | ||
ARRAY | ||
BLOB | ||
CLOB | ||
REF | ||
BOOLEANINT | boolean | Represented as numeric 0 or 1 in DB to represent FALSE or TRUE respectively. |
BOOLEANCHAR | ||
DOUBLE |
I do not use the torque ID Broker. I haven't gotten it to work yet (when I execute "ant -buildfile build-torque.xml id-table-init-sql" it generates an empty oracle-id-table-init.sql file), so I still use my own ID broker (PrimaryKeyGenerator.java).
Some of these things may already be there. I'm not sure:
PreparedStatements should be standard. I shouldn't need to do a search and replace to force torque to use them for select statements. (My ant target automatically does this replacement everytime I use ant to execute torque, but I'd prefer to set that info in a properties file instead of having to do a source code replace.)
Support for hierarchical objects which optionally load parts on demand instead of loading all data all at once. I have projects where I have a single object that represents multiple tables. Such an object would never load anything from any table until an accessor is used to access a value which comes from a table that hasn't been loaded yet. At that time it loads all the values from a row in that table. This is obviously a complex subject and I don't know if it could be adequately expressed in a schema.xml file, but it might be worth some investigation.
Support for automatic caching of objects in a way that allows them to expire after certain lengths of time or if the user decides, based on other criteria, that a newer version is available in the DB. Torque has some caching stuff (the generated manager classes), but it's apparently still considered to be sort of alpha at this point.
I'd prefer to be able to specify everything in the ant task rather than have a special properties file (in my example it was "gamerprofTorqueBuild.properties"). That way, I can specify everything in the ant script if I want to, or I can create my own properties file and load from it using ant if that floats by boat.
I'd like to be able to specify, in the schema, information that can be used to do runtime verification of values. For instance, I might want to specify minimum and maximum values for integers. It should be possible to turn the verification off at runtime if desired (controllable per-table). It should be possible to prevent any of the verification code from being generated at all (some people might consider it pointless overhead). It should be possible to create verification plugins which could be easily added to torque.