[an error occurred while processing this directive]
> developer > web app development
Accessing Data with JDBC in a J2EE World
by Mike Foley, Quality Assurance, Novell
Date Created: 2000-10-31 10:58:00.000
  Why Not AgData?
  Database Connection Pool
  Result Sets
  Slightly More Advanced Stuff
  A Great Book
  Summary

If you are like most SilverStream developers, you probably access data with either an AgData or a Data Source Object (DSO). These objects deliver ease-of-use and added value, but as the emphasis on J2EE standards increases, you may find yourself using AgData and DSOs less and less, and turning to J2EE standard approaches instead.

why not AgData?
The first time I used SilverStream, I was overcome with joy to find an AgData object-it made putting data on my forms and pages so easy. Since then, AgData objects have given me the flexibility I need most of the time. In those rare circumstances when I need to do something beyond the functionality of an AgData object, I step up to using a DSO. So with two powerful and easy-to-use data access objects, why would I consider a different approach?

The answer is simple: portability across J2EE-standard application servers. If your application requiressuch portability, then the proprietary nature of AgData objects and DSOs should be considered. And there is a tradeoff. To gain portability, you will give up considerable ease-of-use and familiarity with AgData objects and DSOs. But, if portability tips the balance for you, you should consider either JDBC or EJB entity beans to manage data access.

Following is a brief introduction on taking a more J2EE compliant approach to JDBC access for the developer.

database connection pool
The database connection pool provides added value in that it allows the sharing and re-using of database connections, thereby boosting application performance. But, this value-added functionality is not part of the J2EE standard.

So if you've been programmatically getting a connection from the SilverStream database connection pool, you've probably been using code similar to this:


	AgiDatabase db = null;

	java.sql.Connection conn = null;

	db = evt.getDatabase() ;  // get the default database

	conn = db.getConnection(true); // gets a connection from the db connection pool



Now with JDBC, you would want to use code like this:


	Class.forName("com.sssw.jdbc.oracle8.Driver");

	String url = "jdbc:sssw:oracle:BLUEFISH"  // a JDBC connection URL to an Oracle database

	Connection conn = DriverManager.getConnection(url, "system", "manager")

results set
When I began accessing data without using an AgData object, I realized I'd been taking a lot of things for granted. One of these things was data navigation. It's just so easy to navigate rows by clicking on a few arrows.



It's also easy to navigate rows in a result set programmatically. You just call the next() method on the result set.

I also took data access for granted. The values from the database just showed up in the text boxes on my form or page automatically. But it's also not too difficult to access data in a result set. Simply call these getXXX or setXXX methods on the result set. Like so:


	Statement stmt = conn.createStatement();

	ResultSet rs = stmt.executeQuery("SELECT LAST_NAME, FIRST_NAME FROM CUSTOMERS");



	while (rs.next() ) {

	System.out.println( rs.getString("LAST_NAME") + "  , "  + rs.getString("FIRST_NAME");

}

point-to-point
The P2P model centers on a queue. A queue is different from a topic in that it will retain messages even if there are no receivers at the time the messages are sent to the queue. Also, once a message has been consumed from a queue, it will not be delivered to any other consumers. Although the JMS specification doesn't define how a queue should behave if more than one receiver is connected, a typical behavior would be to round robin messages from the queue to the receivers. Portable applications should only have one receiver per queue.
slightly more advanced stuff
Once you get the hang of result sets, you'll begin to see that there are some additional things you can do. For example, you can programmatically find out a lot of meta information about your result set and your database.

The example below shows how you can access result-set meta data information, such as column names and column types.


	// get the meta data of the result set

			rsmd = rs.getMetaData();

			numberofColumns = rsmd.getColumnCount();

			rowCount=1;

			while (rs.next() ) {

			System.out.println("Row " + rowCount + ": ");

				for (int i = 1; i <=numberofColumns; i++) {

					System.out.print("    Column " + i + ": " + "Table:" + 							rsmd.getTableName(i) +  " Data type:" + 								rsmd.getColumnTypeName(i) + "  casesensitive: " + 							rsmd.isCaseSensitive(i) + " ispossiblywritable: " + 							rsmd.isWritable(i));

					System.out.println(" Value: " + rs.getString(i));

				}

			System.out.println("");

			rowCount++;

			}



	


This example shows how you can access information about your database:


 		// get meta data from the database

		 dbmd = conn.getMetaData();

		 System.out.println("Database meta data");

		 System.out.println("Keywords used by this database (that are not also SQL92 keywords:"

		 + dbmd.getSQLKeywords() );

		 System.out.println("String functions used by this database: " +

		 dbmd.getStringFunctions() );

		 System.out.println("The search string escape used by this database: " +

		 dbmd.getSearchStringEscape() );

		 System.out.println("The maximum number of characters in a column name: " +

		 dbmd.getMaxColumnNameLength()) ;

		 System.out.println("allProceduresAreCallable :" + dbmd.allProceduresAreCallable() );

		 System.out.println("allTablesAreSelectable :" + dbmd.allTablesAreSelectable() );

		 System.out.println("nulls are sorted high:" + dbmd.nullsAreSortedHigh() );

		 System.out.println("nulls are sorted low :" + dbmd.nullsAreSortedLow() );

		 System.out.println("Database Product Name" + dbmd.getDatabaseProductName() );

		 System.out.println("Database Product version" + dbmd.getDatabaseProductVersion() );

		 System.out.println("Driver name :" + dbmd.getDriverName() );

		 System.out.println("Driver version :" + dbmd.getDriverVersion() );

		 System.out.println("supports mixed case identifiers :" +

		 dbmd.supportsMixedCaseIdentifiers() );

		 System.out.println("stores mixed case identifiers :" + dbmd.storesMixedCaseIdentifiers() );

		 System.out.println("supports alter table with drop column:" +

		 dbmd.supportsAlterTableWithDropColumn() );

		 System.out.println("supports full outer joins :" + dbmd.supportsFullOuterJoins() );

		 System.out.println("max statement length :" + dbmd.getMaxStatementLength() );

		 System.out.println("About to get primary key information");dbmd =
		 
a great book
To learn more on the subject, check out JDBC Database Access With Java: A Tutorial and Annotated Reference by Hamilton, Cattel, and Fisher. I'd highly recommend it for anyone beginning to use JDBC.
summary
We all know how wonderful AgData objects and DSOs are, and have grown accustomed to using them in our applications. We've probably even taken them for granted a few too many times. But for portability across J2EE application servers, you might want to consider other approaches to accessing data, such as JDBC. This article touched upon the use of JDBC for the SilverStream developer. Hopefully you now see that accessing data with JDBC is not too difficult; and perhaps, you've also gained a new and deeper understanding of the true value AgData objects and DSOs can provide.