Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

J2EE Design Strategies That Boost Performance : Page 3

Your J2EE application is up and running, but you've got problems. The response time is slow, the batch-processing throughput is woeful, and the users are complaining. Learn how the application of a few key design strategies can alleviate your performance problems.


advertisement
Database I/O Optimization Implementation—Pure JDBC for Read-only Access
Entity beans provide an abstraction layer between the higher-level business components and the database. When a developer makes a call to a method on a bean, he or she doesn't see what happens under the covers because it's transparent. The developer can assemble large objects or data structures using many entity calls. He or she can be oblivious to the expensive low-level database I/O taking place. One way to alleviate this bottleneck is to replace your critical sections with specialized pieces of pure JDBC code that are optimized for the task. DataAccessObjects (DAOs) and FastLaneReaders (Marinescu/J2EE Blueprints) are common techniques for accelerating reads. These patterns give you fine-grained control over your queries for efficient read access. A DAO can be used to consolidate many DBMS requests made by an entity bean (finder + loads) into a single JDBC call. DAOs are useful for supporting search screens or requests over data that span multiple beans and/or database tables.

The following are recommended practices for DAO:

  • Use your DAO to query for data directly from the DBMS rather than via your entity beans. Session beans and other components can call your DAO directly.
  • Design your DAO so that it can be tailored to return only what you need.
  • Design your DAO so that it can limit the number of rows returned.
  • Use finally clauses to ensure that all JDBC resources are closed when you're finished with them. This ensures that you don't hog or consume connections and cursors.
  • Query against DBMS views to make your DAOs more reusable and portable. If you need to make a change to a query, make a change to the view instead.

With a DAO you can take advantage directly of the features provided by the JDBC API, including:

  • PreparedStatements to pre-compile frequently executed SQL statements
  • Batch methods on the Statement class (addBatch() and exectuteBatch()) to batch up multiple SQL calls into one hit to the database
  • Row limiting (The Statement and ResultSet classes provide methods (setMaxRows() and setFetchSize()) to limit the number of rows returned and set hints for ResultSet fetch sizes.)



See Listing 1: A Simple DAO for executing SQL against a view and limiting the number of rows returned in a ResultSet.

As part of your DAO design, you must decide in which form the data should be returned and how it should be converted. In some cases, you may want to return loosely typed collections such as Lists or Maps, and in other cases you may want to immediately convert ResultSet data into strongly typed Java objects relevant to your system. One way to handle this at the DAO level is to use a helper ResultSetConverter interface. This interface is responsible for converting RowSets into strongly typed application object types or collections. The DAO uses it to automatically convert ResultSet data into your target object(s):

public interface ResultSetConverter { public Object toObject(ResultSet rs) throws Exception; }

Create a simple ResultSet to Map Converter class by implementing the ResultSetConverter interface. Inside the toObject() method, pull the data from the result set and place it into a map of column name/value pairs. The map is returned to the DAO to be passed back to the DAO caller:

class MapConverter implements ResultSetConverter { public Object toObject(ResultSet rs) throws Exception { Map map = new HashMap(); ResultSetMetaData meta = rs.getMetaData(); // Load ResultSet into map by column name int numberOfColumns = meta.getColumnCount(); for (int i = 1; i <= numberOfColumns; ++i) { String name = meta.getColumnName(i); Object value = rs.getObject(i); // place into map map.put(name, value); } return map; } }

To use your DAO and converter, acquire a DAO instance and invoke the query() method to execute your SQL. Use the rowLimit parameter to limit the number of rows returned and pass in the converter class for the DAO to use.

DAO dao = DAO.get(); // Create our own converter for getting the first column as a String ResultSetConverter myConverter = new ResultSetConverter() { public Object toObject(ResultSet rs) throws Exception { return rs.getString(1); } }; // Execute a query against a VIEW,
limit the number of rows returned to 10 and use myConverter to convert the results List data = dao.query("myView", 10, myConverter); // Do something with the data, ship to the JSP etc.

The J2EE Performance-tuning Trade-off
Experienced practitioners know that when addressing J2EE application performance issues, there are no silver bullets. Performance tuning is a trade-off between architecture concerns, such as flexibility and maintainability. Performance increases are won by combining different techniques, patterns, and strategies.

And if all else fails, you can hope that that extra-fast machine you ordered turns up sooner rather than later. :)



Lara D'Abreo is an independent consultant responsible for many commercially released Java products in the telco, database, and integration spaces. She is currently working on software to monitor application servers. to e-mail Lara.
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap