Sie sind auf Seite 1von 24

JAVA WEB

DATABASE APPLICATION DEVELOPMENT

VOLUME I:

FROM SQL AND JDBC TO HTML AND BACK

SNEAK PEEK FIRST EDITION 1.0.1 - JANUARY 2012

Howard Hyde

www.JavaWebDB.com

Copyright© 2012 by HowardHyde. All rights reserved

CONTENTS

CONTENTS

2

PREFACE 4 Value Proposition

Biases 4 How to read this book:

4

5

PART I: FROM SQL AND JDBC TO HTML AND BACK

CHAPTER 1: SERVLETS, JSP, JDBC

8

7

The Rationale and Purpose of Java Servlets

8

Application Components and Infrastructure

8

One-Minute Java Primer

12

Coding Servlets and Java Server Pages (JSP)

14

CHAPTER 2: YOUR FIRST JAVA WEB APP

18

Installing the source code

A trivial JSP application: (Bogus) Stock Quoter 18

The same app written as a servlet 24

A variation on the servlet-based implementation

The same app enhanced with Javascript and Cascading Style Sheets (CSS) 42

Summary 51

18

34

CHAPTER 3: INTRO TO JDBC JDBC 52

JDBC Drivers

Database Connnectivity Architecture

JDBC Connection Parameters

52

52

55

53

JDBC Objects and Methods to establish the connection

56

JDBC Objects and Methods to execute an SQL Query

59

JDBC Objects and Methods to execute SQL DML

60

JDBC Objects and Methods to execute Stored Procedures

61

JDBC Exceptions Summary 62

62

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

CHAPTER 4: YOUR FIRST JAVA WEB DATABASE APP Example Application: Aviation Scheduling: ‘FBO Ace’ 63

63

Database Setup and Design

65

Application Architecture: Model/Data, View, Controller

67

Airport.java 67 Digression regarding data bean code generation

70

Digression regarding error handling and communication

71

Query and Persistence Methods

73

Application Home Page: Index.jsp

80

The Database Application Configuration (web.xml) File

82

Outlining Your First Database Servlet: AirportServlet.java

84

Coding the Servlet

processPageBody() 88 airportViewEditForm() 91 persist() 94 getJDBC2Connection() 97

85

CHAPTER 5: DATABASE CONNECTION POOLING AND JNDI

98

Configuration Checklist

98

Coding the app to use JNDI JDBC resources

100

CHAPTER 6: NUMBERS, DATES, LISTS AND BOOLEANS

103

The Aircraft Table

103

Data Bean Template104

 

Aircraft.java 110

The Aircraft Data Maintenance Form

115

Configuring The Aircraft Servlet

117

The Aircraft Servlet Code

119

The UI method: aircraftViewEditForm() 122 The Save method: persist() 133

 

CHAPTER 7: DATA MODULES WITH FOREIGN KEY LOOKUPS

140

Example Application: Aviation

140

Database App 3: Flight with FK References to Aircaft and Airport.

146

148

Digression: Active/Emphatic vs. Passive NULL 152

Setters and updateStatus(): Intelligent update control 155

Airport.java, Aircraft.java and Flight.java

Retrieval methods

Heavy lifting: saveToDatabase()

158

159

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

Delete and Commit 166 FlightServlet.java 169

CHAPTER 8: COMPLEX MASTER-DETAIL DATA MODULES

DBWebApp04 Home Page: Index.jsp

Airport, Aircraft, Pilot and Flight_Pilot_Type Modules The Master-Detail Flight Module 194 import com.RADInfoDesign.jwdbappdev.util.Util;

Abstract class DBAppDataBean

188

190

200

202

188

Flight.java 209 Flight_Pilot.java 218 FlightServlet.java 220 processPageBody() 223 flightViewEditForm() 229 JDBC Transaction Autocommit Mode persist() 241

241

CHAPTER 9: EPILOGUE TO PART I

251

PART II: PERSISTENCE APIS AND FRAMEWORKS

COMING SOON IN VOLUME II

258

258

PART III: ENTERPRISE APPLICATION ARCHITECTURE CONSIDERATIONS COMING SOON IN VOLUME III 259

259

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

PREFACE

Value Proposition

Other fine books are available on Java-based database and web technologies such as SQL, JDBC, JNDI, Servlets, JSP, Javascript, CSS etc. What this book intends to offer is a unique synthesis of the above, from a unique perspective deeply rooted in the relational paradigm, which challenges you the Java programmer to make a true value-added contribution to the architecture. I will confess my utter lack of visual or graphic design skills, while assuring the artists in my audience that their work will given their place in the architecture to plug in and work their magic.

Biases

There are unlimited variations possible in approaches to software development with a single technology, to say nothing of a system that in pursuit of a comprehensive solution combines a dozen significant technologies, some of which may be supported by different vendor’s products. In particular, the examples in this book were developed and are demonstrated on a specific platform:

Database: Oracle. We don’t get into advanced features of the relational database management system (RDBMS), but there will be minor syntactical variations between the examples in this book and your database, if it is MySQL, MS SQL Server, IBM DB2, Sybase, Informix, or another.

Web/Application Server: Apache Tomcat. Again, we will not go very deep into proprietary features, so with the exception of variations related to JNDI and database connection pooling (subject of Chapter 5), your application should run without modification on any JEE-compliant server platform: Weblogic, JBoss, GlassFish, Websphere etc.

Java Servlets. Servlets are the dominant technology we will use to impement the Controller and View (dynamic HTML embedded in Java) functions of our application, with standard (and not-so-standard) Javabean classes performing the Model/data function. Other approaches are possible including those that emphasize

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

Java Server Pages (JSP), Java Server Faces (JSF) and/or Enterprise Java Beans (EJB). Even so, servlets are the common denominator and underlying engine of all of these options. They offer a rich and highly practical platform (at the very least a very effective training ground) for development of web-based applications, giving the developer complete programatic control. Even if you consider JSF to be the new supersonic fighter jet with all-electronic instruments (‘glass cockpit’) and fly-by- wire controls, it will pay dividends to learn first to fly a propeller airplane with gyroscopic, magnetic and pitot-static instruments 1 and mechanical, pulley-and- cable controls (servlets are a cut above that!).

Some of my biases go beyond the choice of vendor’s products and technologies and extend to methodologies and design paradigms. Some readers will disagree with my approach. To those I hope that even in disagreement you can use my examples as a point of departure for alternatives. And I welcome your comments and feedback. This is a journey that never ends.

How to read this book:

Hint: Start on Chapter 1 (or 2 if 1 is too elementary for you) and turn the pages one by one until you get to the end.

That’s not too difficult to get, is it? All of the sample applications and tutorials build upon one another, starting with the most simple, minimalist elements necessary to get an app functioning round-trip from the database to the user’s browser and back; then incrementally increasing the complexity and advancing to more enterprise-scalable solutions. Advanced pros may skim to accelerate to the parts more interesting to them, but if you skip sections or chapters entirely, some lessons and tutorials might not make sense; you won’t understand the rationale behind the methodology. So strap in for a step-by-step, progressive journey as opposed to a random access to a reference book.

1 Aviation metaphors will pervade this volume. Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

PART I: FROM SQL AND JDBC TO HTML AND BACK

In this part, we’ll get you productive as quickly as possible with the basic concepts and mechanics of database application development with JSP and Java servlets. We outline the architecture, introduce our example application data model, expose the essential JDBC and servlet classes and methods, and get our hands dirty with a working, full data lifecycle web application.

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

CHAPTER 1: SERVLETS, JSP, JDBC AND DATABASE

The Rationale and Purpose of Java Servlets

Java servlet technology allows client applications running in a browser over a TCP/IP network (like the Internet, internal enterprise ‘intranets’ or external ‘extranets’) to invoke complex programmatic functionality that goes beyond simple retrieval of static HTML and graphic files. It offers significant performance and other improvements over the earlier Common Gateway Interface (CGI) technology that was first developed in the early 1990’s to provide this capability. CGI programs had to wake up, allocate memory, execute, deallocate memory and die with each client request, thereby creating a heavy, poorly- scaling overhead burden without any possibility of managing session state. Servlets on the other hand stay resident in memory to serve a theoretically unlimited number of requests. Servlets can maintain global attributes across requests such as persistent database connections. And they’re written in the platform-independent, powerful and popular object-oriented language of Java.

Application Components and Infrastructure

When we discuss servlet development, there are certain assumptions that may be made about the system architecture, or ‘platform’ for which we are developing. Servlets do not have a graphical user interface (GUI) of their own; they execute within the memory space of a webserver ‘container’ residing on a server machine, typically in a back- office data center. Servlets may write output to the server console, but their primary function is to process HTTP requests received from browser clients and to send responses back in the form of HTML and related content which the browser may render graphically for the user.

So we assume the presence of the following application components:

TCP/IP network: Transport Control Protocol / Internet Protocol is the fundamental communication mechanism of the Internet, and all vendors of Local Area Network …

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

CHAPTER 2: YOUR FIRST JAVA WEB APP

This chapter will demonstrate the basic mechanics of the HTTP request/response cycle as

implemented with JSP and Servlets. We will leave the database aside for the moment.

Installing the source code

The source code for the 8 sample applications that we will walk through in the next

chapters is in the file bundle that accompanies this book, under the directory /webapps, in

the following subdirectories:

/webapps

o

/BogusStockQuote01

o

/BogusStockQuote02

o

/BogusStockQuote03

o

/BogusStockQuote04

o

/DBWebApp01

o

/DBWebApp02

o

/DBWebApp03

o

/DBWebApp04

You should be able to drop these directories and their files into the deployment directory of

your web/application server (/webapps in the case of Tomcat) and run the apps. Starting

with /DBWebApp01, the database apps will require customization of the web.xml

configuration file to match the database connection parameters specific to your

environment.

A trivial JSP application: (Bogus) Stock Quoter

Our first app will consist of just two JSP files. When a user invokes a valid application URL from a browser without specifying the exact file (or servlet) name, the server will either display a directory listing or invoke a ‘welcome file’. Which file serves (or may serve, in

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

CHAPTER 3: INTRO TO JDBC

In this chapter, we present bare-bones essential information on how Java applications

communicate with relational databases. This will pave the way for our first sample Java

web database application in the next chapter.

JDBC

JDBC™is a trademarked technology created by Sun Microsystems for communicating

between Java clients and relational databases. JDBC provides classes and methods for a

Java-based clients to:

connect to a database

define and execute queries (SQL SELECT) against a database

define and execute SQL DML (insert, update, delete) against a database

define and execute stored procedures with IN, OUT, and INOUT parameters

retrieve results sets, OUT parameter values and return values from database queries and stored procedures.

…and much more.

The next several sections will detail the basics of using JDBC with servlets.

JDBC Drivers

The main manifestation of the JDBC technology is the driver, the piece of software that

translates Java code and objects into commands and datatypes compatible with the SQL

database you are connecting to, and manages the communication. JDBC drivers are

classified by Type, of which there are 4:

1. JDBC-ODBC bridge. In this model, the JDBC driver acts as a Java wrapper around the

more generic industry-standard ODBC driver. An additional ODBC driver is required.

2. Native API – Partly Java Driver. This type of driver communicates to each database in its

proprietary protocol, but the driver itself is only partly implemented in Java and therefore

requires additional platform-specific binary code, such as Windows DLL’s.

3. JDBC-Net Pure Java Driver. This driver is implemented entirely in Java and

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

CHAPTER 4: YOUR FIRST JAVA WEB DATABASE APP

In this chapter we’ll develop an application which queries, displays and provides insert, update and delete functionality on rows of a single database table with simple datatypes. In the process we’ll learn a bit more about using JDBC database connections, and how to divide data, presentation and application functionality responsibility among Javabeans (or ‘Java data beans’), view and controler (servlet) classes and methods. These elements will evolve in the rest of the book as we explore database applications of increasing complexity. (See source code subdirectory /DBWebApp01 for this chapter’s application.)

Example Application: Aviation Scheduling: ‘FBO Ace’

The application and code examples in this book are mostly based on a very basic version of an aviation scheduling database system I call ‘FBO Ace’ (FBO stands for Fixed Base Operator, which is a term used to describe businesses that offer fuel, maintenance, scheduling and pilot training services in the General Aviation industry). In later chapters we will present the complete database schema; for this chapter we will introduce just one table in the schema: ‘Airport’.

will introduce just one table in the schema: ‘Airport’. Two main views of this table will

Two main views of this table will be presented to the user in the browser UI:

A read-only listing, and

An editable data maintenance form with options to create new and modify or purge existing instances.

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

CHAPTER 5: DATABASE CONNECTION POOLING AND JNDI

The way we used database connections in our introductory database application served its purpose, but now we need to get a bit more serious about a database connectivity architecture and methodology that will scale and perform. For this we need the Java Naming and Directory Interface, or JNDI. With JNDI, database connections and other external resources are managed by your container, the web or application server (Tomcat, JBoss, Glassfish, Weblogic, Websphere etc.), separate from your servlets, javabeans, enterprise javabeans (EJBs) or other application classes; and made available to your application classes to use, minimizing the connection management code that you have to write. JNDI has a scope beyond just database connections and JDBC; it can be used to facilitate remote communication among generic Javabeans, UserDatabases (named accounts of web/application server uses), JavaMail sessions and more. For our purposes, we are only interested in the database connection pooling and JDBC-related features.

Because configuring JNDI varies so widely from vendor to vendor, we will concentrate here on basic principles and a few particulars specific to Tomcat, and let you browse the vendor- specific documentation for greater depth. Working with technical documentation from vendors and reference sites can be an exercise in frustration. I remember well when I was first learning this a decade ago, trying several configurations that I thought should have been correct, only to get error messages when I attempted to run my app. When I finally found a configuration that worked, I realized that some elements I had put in place (because the documentation told me to) were superfluous, and so I removed them.

Configuration Checklist

The example JDBC/JNDI configuration values we show in this chapter is what we will use for our second database application which will be elaborated in the next chapter.

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

CHAPTER 6: NUMBERS, DATES, LISTS AND BOOLEANS

In Chapter 4 we created a data maintenance form on a simple, single table with only textual datatypes (the Airport_ID is numeric, but since it’s not ‘mathematical’ we could treat it in Java as a String). In this chapter we’ll go another round with a single table data module, but introduce more datatype issues. In this chapter we’ll deal with slightly more complex issues: dealing from the database to the UI and back with numbers, dates, lists and ranges of permissible values, and (quasi-) boolean datatypes rendered as checkboxes. Along the way we’ll refine the craft of using metadata queries to generate clean, consistent code against table and column structures and datatypes. (See source code subdirectory /DBWebApp02 for this chapter’s application.)

The Aircraft Table

Last time we introduced the Airport table of our aviation scheduling schema. For this chapter we introduce the Aircraft table:

schema. For this chapter we introduce the Air craft table: Here is the SQL DDL to

Here is the SQL DDL to create this table, which reveals the more subtle details of its definition, including datatypes and check constraints:

CREATE TABLE AIRCRAFT

(

AIRCRAFT_ID NUMBER NOT NULL, NAME VARCHAR2 (20) NOT NULL, WING_TYPE VARCHAR2 (11) NOT NULL, DESCRIPTION VARCHAR2 (4000), MANUFACTURE_YEAR NUMBER (4) NOT NULL, NEXT_MAINTENANCE_DATE DATE NOT NULL, IN_SERVICE_FLAG CHAR(1) NOT NULL

); ALTER TABLE AIRCRAFT ADD CONSTRAINT AIRCRAFT_PK PRIMARY KEY (AIRCRAFT_ID);

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

CHAPTER 7: DATA MODULES WITH FOREIGN KEY LOOKUPS

As our database application gets increasingly elaborated, it is time to lay out the complete database schema design for the following few chapters. We will only an app against 3 of the 6 tables in the complete schema in this chapter. In the next chapter, we will use all 6. (See source code subdirectory /DBWebApp03 for this chapter’s application.)

Example Application: Aviation

The example application subject is aviation: scheduling flights matching pilots to aircraft travelling between airports. The model and table attributes will be kept very simple (please, no complaints that you can’t run Virgin InterGalacticWarp Airlines on these six tables). As we stated earlier, we use a surrogate-key design, where tables have one or more meaningless numeric columns comprising its primary key; in addition, some tables will have alternate unique keys for natural business-level identifiers.

The Data Model Here are the tables we will create for this model (the first two we have seen already):

Airport: This table contains your complete list of all airports served by your organization (or used, unofficially, as emergency landing strips); each row represents a potential departure or destination point for a Flight. Alternate keys Name and on the 3-character code (such as ‘LAX’, ‘JFK’, ‘CDG’ etc).

Aircraft: Each row represents a specific air travel vehicle; taken in the aggregate, this entity represents the organization’s fleet. Alternate key on ‘name’ column, which in practice here represents the registration or ‘N-’ number (in the United States), i.e. ‘N742ST’.

Flight: Represents a scheduled instance of one or more Pilots flying an aircraft between airports. Alternate unique key on business-level ‘Flight_Number’ column, which can be an alphanumeric value entered manually or derived from other attributes or automated algorithm as required.

Pilot: Person qualified to manage the controls of an aircraft in flight.

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

CHAPTER 8: COMPLEX MASTER-DETAIL DATA MODULES

In Chapter 7 we completed our 6-table data model and schema, and built an app that operated on one and referenced two more. Here we will complete an app that provides the user with data maintenance forms against all 6 tables, including a capstone module that allows editing of new or existing Flights and Flight-Pilots in a master-detail form with references to the other 4 tables; all 6 tables represented in a single cohesive business object. (See source code subdirectory /DBWebApp04 for this chapter’s application.)

DBWebApp04 Home Page: Index.jsp

Below is the new Home or landing page for the app. As you see, it is a menu offering navigation to all of the individual data modules.

offering navigation to all of the individual data modules. Figure 8-1: DBWebApp04 / FBO Ace Home

Figure 8-1: DBWebApp04 / FBO Ace Home Page

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

The Master-Detail Flight Module

The real ‘red meat’ of this chapter is the new Flight module, which allows the user to add or edit multiple records from 2 tables simultaneously in a Master-Detail view. The landing page for the Flight servlet is (as usual) the read-only/List view. The reader will notice 3 new elements this time:

A link back to the Main Menu (index.jsp a.k.a. Home page)

A button labeled ‘Create New’

‘Edit’ buttons in each row of the list view table. Here’s what it looks like:

row of the list view table. Here’s what it looks like: Figure 8-2: Master-Detail Flight Module

Figure 8-2: Master-Detail Flight Module in Read-Only/LIST mode

Instead of having the user edit all flights at once, clicking on the [Edit…] button in a chosen row brings up the Edit form for that flight, with the master Flight record displayed in a top block and the detail Flight-Pilot records shown in a separate block below.

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

Here’s how it looks:

Here’s how it looks: Figure 8-3: Master-Detail Flight Module in EDIT Mode The reader will note

Figure 8-3: Master-Detail Flight Module in EDIT Mode

The reader will note that the Master block is shown this time with Flight attibutes listed vertically, while the child block retains the columnar grid design established earlier.

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

The four referenced tables are represented as pull-down menus from which the user may make choices:

as pull-down menus from which the user may make choices: Figure 8-4: Drop-Down FK List Boxes

Figure 8-4: Drop-Down FK List Boxes on Edit Flight Form

Other elements to note:

The user may modify any of the elements of Flight or Flight-Pilot by editing the fields or making pull-down menu choices in place, then clicking [Save to Database.]

New Flight-Pilot records may be added one at a time in the child block. Adding new whole Flights requires entering the form from the List view in New mode by clicking that form’s [Create New…] button (see below).

Existing Flight-Pilot records may be deleted in the usual way; check the box in the [Delete?] column of the child grid in the intended row and then click [Save to Database].

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

The Pilot field in the child Flight-Pilot block is read-only for exising records, selectable for new records. Pilot_ID is a member (co-equal with Flight_ID) of the primary key of the Flight_Pilot table; part of its fundamental definition which ensures that a given Pilot may only be assigned to a given flight once. If one Pilot should be exchanged for another for a given Flight, this requires a delete-insert; delete the old, insert the replacement.

The user may (attempt to) delete the Flight by checking the [Delete?] checkbox at the bottom of the master block and clicking [Save to Database]. What happens next depends on whether there are any child records in the Flight-Pilot block and whether or not the foreign key from flight_pilot to flight is enforced, and whether or not CASCADE DELETE is implemented on the foreign key. In case of a constraint violation, the SQL statement will fail and the user will receive a message such as:

“Sorry, SQL Delete failed. This may be a business rule violation or a program bug. If you think it is a bug, Please contact support at 1(800)FAT-CHANCE.” If on the other hand the SQL delete succeeds, the user is returned to the List view of the Flight module.

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

Clicking the [Create New…] button on the List screen brings up a form similar to the one we just saw, except with all fields blank and no pull-down menu choices pre-selected.

all fields blank and no pull-down menu choices pre-selected. Figure 8-5: Master-Detail Flight Module in NEW

Figure 8-5: Master-Detail Flight Module in NEW Mode

This screen permits the user to create up to 1 new Flight plus 1 new related Flight-Pilot record at a time (Flight-Pilot records may NOT be created indepenently of Flights in our app). Upon Save, the user is returned to the Edit form for the same Flight, where (s)he may edit the records just created and/or add more Flight-Pilot records.

That’s how it looks and feels (with rudimentary visual design). Now let’s dive into the guts of how it is built.

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

CHAPTER 9: EPILOGUE TO PART I

We’ve come a long way. We started with the simplest of all possible database applications, a single table with a few text columns in it, and figured out the minimum 3-tier infrastructure needed to make that available to multiple users over the web. From there we proceeded by increments to deal with more complex data types and relationships and to reinforce the architecture (such as connection pooling) to make the solution scalable for large enterprises, datastores and user populations. Along the way, we practiced functional decomposition and the separation of model, view and controller functions; created a standard servlet-and-Javabean class and method framework for the complete cycle of database interactivity; established a flexible methodology for formatting, presenting and receiving dates and date-time values; built minimalist logic to interpret the user’s intent with respect to the creation, modification and/or erasure of data; put in safeguards against crippling NullPointerExceptions; and more. Our capstone application blended the object-oriented and relational paradigms to escape the prison of the one-class-one-table model and establish a new standard unit of interaction:

The rich business object having one unitary driving entity (Flight), one or more potentially multi-valued child entities (Flight-Pilot) and any number of referenced entities, qualifiers or dimensions (Airport, Aircraft, Flight Pilot Type, Pilot), any of which could be the driving entity of its own simple or complex business object. From that unit, enterprise applications of any extent may be constructed.

Even so, there is so much more we could do, right? Here are some advanced topics that could be developed in a future expanded edition of this book (for now, they are YOUR extra-credit assignments):

Working with advanced datatypes. In our sample apps, we’ve only dealt with 3 basic datatypes and one variation:

CHAR/VARCHAR, NUMBER and DATE/DATETIME. We didn’t do any advanced

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

PART II: PERSISTENCE APIS AND FRAMEWORKS

COMING SOON IN VOLUME II

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

PART III: ENTERPRISE APPLICATION ARCHITECTURE

CONSIDERATIONS

COMING SOON IN VOLUME III

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.

Stay tuned at www.JavaWebDB.com for updates, new editions, articles, FAQs and commentary.

Java Web Database Application Development Copyright© 2012 by Howard Hyde. All rights reserved.