Summary
In this chapter we've surveyed some of the most effective data-access approaches for J2EE applications. We've considered:SQL-based approaches, such as JDBC and SQLJ. These can deliver very high performance, with minimal overhead, when we are working with relational databases and when O/R mapping is inappropriate. (We discussed the criteria for deciding whether to use O/R mapping in Chapter 7.) As most J2EE applications use relational databases, SQL-based approaches are very important in practice.
Approaches based on O/R mapping, such as proprietary O/R mapping frameworks and JDO. JDO is particularly worthy of attention, as it may emerge as the standard J2EE API for accessing persistent data, whether in RDBMSs or ODBMSs.
All the approaches discussed in this chapter can be used in either the EJB container or web container of a J2EE application server. They can also easily be tested outside a J2EE application server: an important consideration, as we saw in Chapter 3. We can use any of these strategies in entity beans with BMP, but, as we have seen, BMP is unusable in many cases and imposes a complex, prescriptive model that delivers little or no benefit.We concluded that a SQL-based approach using JDBC was most appropriate for our sample application, as it could not benefit significantly from caching in an O/R mapping layer, and because we saw in Chapter 7 that we can make effective use of stored procedures to move some of its persistence logic into the RDBMS. However, as we don't want our application's design to be dependent on use of an RDBMS, we chose to use the DAO pattern to conceal the use of JDBC behind an abstraction layer of persistent-store-independent interfaces.As the sample application will use JDBC, we took a closer look at the JDBC API. We saw the importance (and difficulty) of correct error handling, how to extract information about the cause of a problem from a javax.sql.SQLException, and the pros and cons of JDBC PreparedStatements and Statements.We concluded that using the JDBC API directly isn't a viable option, as it requires too much code to be written to accomplish each task in the database. Thus we need a higher level of abstraction than the JDBC API provides, even if we don't want to use an O/R mapping framework.We examined the implementation of a generic JDBC abstraction framework, which delivers such a higher level of abstraction. We use this framework in the sample application, and it can be used in any application working with JDBC. This framework offers two levels of abstraction:
The com.interface21.jdbc.core package, which uses callback methods to enable the framework JdbcTemplate class to handle the execution of JDBC queries and updates and JDBC error handling, relieving application code of the commonest causes of errors when using JDBC.
The com.interface21.jdbc.object package, which builds on the com.interface21.jdbc.core package to model each RDBMS query, update, or stored procedure invocation as a reusable, threadsafe Java object, entirely concealing SQL and JDBC usage from application code. Using this package, we can greatly reduce the complexity of code using JDBC.
next chapter we'll look at effective use of session EJBs.