Choosing Technologies


After the ERD is complete, you can create your database schema from it. At this point, you need to begin making a list of the technologies that you'll use to develop the application.

This application would be a good candidate for Struts for several reasons. For one, it has some flows between different parts of the site that must be controlled to ensure correct authentication and access control. In addition, there are some forms with moderately complex validations that must be run, and Struts offers easy form validation, as you'll see.

Having chosen Struts, you have a wide choice of platforms to run it on. You probably don't have tens of thousands of dollars to spend to try out a sample application, so the Jakarta Tomcat platform is a good choice because it's both free and reliable.

Similar factors might lead you to choose the MySQL database for the data storage portion of the application. One of the nice features of applications written using JDBC is that it's easy to move them between databases, so you could move to Oracle or another commercial database product if your needs grow larger.

Torque

By using the Torque object-modeling tool, you can make it even easier to move between databases. Torque is a wonderful new tool from the Jakarta team that automatically creates a set of Java objects that map one-to-one against database tables, including foreign key relationships. It's worth taking a brief moment to see how Torque works.

The heart of Torque is the project-schema.xml file. This file describes, in vendorneutral terms, the structure of your database. Listing 6.1 shows the project-schema.xml file for this application.

Note

As with all other source code in this book, you can find this file on the companion CD with this book.


Listing 6.1 project-schema.xml
 <?xml version="1.0" encoding="ISO-8859-1" standalone="no" ?> <!DOCTYPE database SYSTEM "file:/torque/schema/database.dtd"> <!-- ==================================================================== --> <!--                                                                      --> <!-- STOCKTRACK T O R Q U E S C H E M A                               --> <!--                                                                      --> <!-- ==================================================================== --> <!--   Note: You must now specify a database name. --> <database name="stocktrack"   defaultIdMethod="native">   <table name="STOCK">     <column name="STOCK_ID" primaryKey="true" required="true"                             autoIncrement="true" type="INTEGER"/>     <column name="STOCK_SYMBOL" required="true" type="VARCHAR" size="10"/>     <column name="STOCK_LONG_NAME" required="true" type="VARCHAR" size="30"/>     <column name="STOCK_TYPE_ID" required="true" type="CHAR" size="1"/>     <foreign-key foreignTable="STOCK_TYPE">       <reference local="STOCK_TYPE_ID" foreign="STOCK_TYPE_ID"/>     </foreign-key>   </table>   <table name="STOCK_TYPE" idMethod="none">     <column name="STOCK_TYPE_ID" primaryKey="true"             required="true" type="CHAR" size="1"/>     <column name="STOCK_TYPE_DESCRIPTION" required="true"             type="VARCHAR" size="50"/>   </table>   <table name="STOCK_PRICE_HISTORY" idMethod="none">      <column name="STOCK_ID" required="true" type="INTEGER"/>      <column name="PRICE_TIMESTAMP" required="true" type="BIGINT"/>      <column name="PRICE_CLOSE" type="CHAR" size="1"/>      <column name="PRICE" required="true" type="FLOAT"/>      <foreign-key foreignTable="STOCK">         <reference local="STOCK_ID" foreign="STOCK_ID"/>      </foreign-key>   </table>   <table name="USER">     <column name="USER_ID" primaryKey="true" required="true"             autoIncrement="true" type="INTEGER"/>     <column name="USER_USERNAME" required="true" type="CHAR" size="15"/>     <column name="USER_PASSWORD" required="true" type="CHAR" size="15"/>     <column name="ADDRESS_ID" required="false" type="INTEGER"/>     <column name="USER_FIRST_NAME" required="true" type="VARCHAR" size="30"/>     <column name="USER_LAST_NAME" required="true" type="VARCHAR" size="30"/>     <column name="USER_EMAIL_ADDRESS" required="false" type="VARCHAR" size="30"/>     <foreign-key foreignTable="ADDRESS">         <reference local="ADDRESS_ID" foreign="ADDRESS_ID"/>     </foreign-key>   </table>   <table name="ADDRESS">     <column name="ADDRESS_ID" primaryKey="true" required="true"             autoIncrement="true" type="INTEGER"/>     <column name="ADDRESS_STREET1" required="true" type="VARCHAR" size="60"/>     <column name="ADDRESS_STREET2" required="false" type="VARCHAR" size="60"/>     <column name="ADDRESS_CITY" required="true" type="VARCHAR" size="30"/>     <column name="ADDRESS_STATE" required="false" type="VARCHAR" size="2"/>     <column name="ADDRESS_POSTAL_CODE" required="false" type="VARCHAR" size="10"/>     <column name="ADDRESS_HOME_PHONE" required="false" type="VARCHAR" size="15"/>     <column name="ADDRESS_WORK_PHONE" required="false" type="VARCHAR" size="15"/>     <column name="ADDRESS_WORK_EXT" required="false" type="VARCHAR" size="10"/>   </table>   <table name="TRANSACTION">     <column name="TRANSACTION_ID" primaryKey="true" required="true"             autoIncrement="true" type="INTEGER"/>     <column name="USER_ID" type="INTEGER" required="true"/>     <column name="STOCK_ID" type="INTEGER" required="true"/>     <column name="AMOUNT" type="FLOAT" required="true"/>     <column name="SHARE_PRICE" type="FLOAT" required="true"/>     <column name="TRANSACTION_DATE" type="BIGINT" required="true"/>     <foreign-key foreignTable="USER">       <reference local="USER_ID" foreign="USER_ID"/>     </foreign-key>     <foreign-key foreignTable="STOCK">       <reference local="STOCK_ID" foreign="STOCK_ID"/>     </foreign-key>   </table> </database> 

Much of this file can be recognized as a direct XML representation of an SQL schema. There are a few features, however, that are important to note.

First, notice the defaultIdMethod and idMethod parameters on the database and tables, respectively. The defaultIdMethod is used to set how Torque handles auto-incrementing columns . If set to native , Torque tries to use the native auto-increment feature of the database it is run against. If set to idbroker , Torque will use its own ID generation mechanism. In this case, using MySQL's auto-incrementing columns is fine.

If you have a table without a primary key (for example, a cross-referencing table), Torque will be confused unless you specify that the table has no ID by using idMethod=none on the table itself.

After you've set up the XML file and a property file that tells Torque which database and connection pooling scheme to use, you use Ant to have Torque automatically use both the SQL files to create the database and the Java files to map classes to tables. For example, Listing 6.2 shows the project-schema.sql file that results from the XML file shown in Listing 6.1.

Listing 6.2 project-schema.sql
 # ----------------------------------------------------------------------- # STOCK # ----------------------------------------------------------------------- drop table if exists STOCK; CREATE TABLE STOCK (     STOCK_ID INTEGER NOT NULL AUTO_INCREMENT,     STOCK_SYMBOL VARCHAR (10) NOT NULL,     STOCK_LONG_NAME VARCHAR (30) NOT NULL,     STOCK_TYPE_ID CHAR (1) NOT NULL,     PRIMARY KEY(STOCK_ID),     FOREIGN KEY (STOCK_TYPE_ID) REFERENCES STOCK_TYPE (STOCK_TYPE_ID) ); # ----------------------------------------------------------------------- # STOCK_TYPE # ----------------------------------------------------------------------- drop table if exists STOCK_TYPE; CREATE TABLE STOCK_TYPE (     STOCK_TYPE_ID CHAR (1) NOT NULL,     STOCK_TYPE_DESCRIPTION VARCHAR (50) NOT NULL,     PRIMARY KEY(STOCK_TYPE_ID) ); # ----------------------------------------------------------------------- # STOCK_PRICE_HISTORY # ----------------------------------------------------------------------- drop table if exists STOCK_PRICE_HISTORY; CREATE TABLE STOCK_PRICE_HISTORY (     STOCK_ID INTEGER NOT NULL,     PRICE_TIMESTAMP BIGINT NOT NULL,     PRICE_CLOSE CHAR (1),     PRICE FLOAT NOT NULL,     FOREIGN KEY (STOCK_ID) REFERENCES STOCK (STOCK_ID) ); # ----------------------------------------------------------------------- # USER # ----------------------------------------------------------------------- drop table if exists USER; CREATE TABLE USER (     USER_ID INTEGER NOT NULL AUTO_INCREMENT,     USER_USERNAME CHAR (15) NOT NULL,     USER_PASSWORD CHAR (15) NOT NULL,     ADDRESS_ID INTEGER,     USER_FIRST_NAME VARCHAR (30) NOT NULL,     USER_LAST_NAME VARCHAR (30) NOT NULL,     USER_EMAIL_ADDRESS VARCHAR (30),     PRIMARY KEY(USER_ID),     FOREIGN KEY (ADDRESS_ID) REFERENCES ADDRESS (ADDRESS_ID) ); # ----------------------------------------------------------------------- # ADDRESS # ----------------------------------------------------------------------- drop table if exists ADDRESS; CREATE TABLE ADDRESS (     ADDRESS_ID INTEGER NOT NULL AUTO_INCREMENT,     ADDRESS_STREET1 VARCHAR (60) NOT NULL,     ADDRESS_STREET2 VARCHAR (60),     ADDRESS_CITY VARCHAR (30) NOT NULL,     ADDRESS_STATE VARCHAR (2),     ADDRESS_POSTAL_CODE VARCHAR (10),     ADDRESS_HOME_PHONE VARCHAR (15),     ADDRESS_WORK_PHONE VARCHAR (15),     ADDRESS_WORK_EXT VARCHAR (10),     PRIMARY KEY(ADDRESS_ID) ); # ----------------------------------------------------------------------- # TRANSACTION # ----------------------------------------------------------------------- drop table if exists TRANSACTION; CREATE TABLE TRANSACTION (     TRANSACTION_ID INTEGER NOT NULL AUTO_INCREMENT,     USER_ID INTEGER NOT NULL,     STOCK_ID INTEGER NOT NULL,     AMOUNT FLOAT NOT NULL,     SHARE_PRICE FLOAT NOT NULL,     TRANSACTION_DATE BIGINT NOT NULL,     PRIMARY KEY(TRANSACTION_ID),     FOREIGN KEY (USER_ID) REFERENCES USER (USER_ID),     FOREIGN KEY (STOCK_ID) REFERENCES STOCK (STOCK_ID) ); 

The Java classes created follow a strict naming convention. For example, for the table STOCK , Torque will create BaseStock , BaseStockPeer , Stock , and StockPeer . BaseStock and BaseStockPeer are automatically re-created each time Ant is run, and should never be edited by the developer. Stock and StockPeer are created only the first time Ant is run; they can then be edited and extended.

Here's a code snippet that shows how Torque is used to talk to the database:

 Criteria crit = new Criteria(); crit.add(StockPeer.STOCK_SYMBOL, "IBM"); List l = StockPeer.doSelect(crit); Stock stock = (Stock) l.get(0); System.out.println("Full name of IBM is " + stock.getLongName()); 

Notice that among other things, Torque has automatically created static variables on the StockPeer class (actually, in the BaseStockPeer class that StockPeer inherits from) that correspond to each of the columns, and getters and setters on the Stock class for each column.

Here's a snippet that shows how to create a new database record:

 Stock stock = new Stock(); stock.setSymbol("IBM"); stock.setLongName("International Business Machines, Inc."); stock.setTypeId("Y"); //NYSE stock.save(); 

As you can see, Torque eliminates most of the pain that used to be associated with persisting Java objects to the database.



Struts Kick Start
Struts Kick Start
ISBN: 0672324725
EAN: 2147483647
Year: 2002
Pages: 177

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net