这几天学习了一下关于JDBC的内容,查了一些资料,其中还有一篇洋文,花了一个1个多小时看了看,其实了解技术方面的知识,还是看洋文更容易理解一些,但是就是费时间,可能是我的英语阅读速度的问题吧! anyway,以后还是多多看看洋文写的文章。
下面把文章贴上来,与大家分享,有点长,大家看的可能会不耐烦,没关系,近期,我会整理一下思路,写个中文的! 主要是讲java序列化与jdbc的优缺点的。
简介: This article examines two data management strategies available on the Java platform: Java object serialization and Java Database Connectivity (JDBC). While neither data management strategy is inherently superior or inferior to the other, when it comes to managing enterprise information systems, JDBC wins hands down. In this article Java developers G.V.B. Subrahmanyam and Shankar Itchapurapu look at both serialization and JDBC, and through discussion and example show you why JDBC is your best bet.
When you're building an enterprise information system, you need to make sure that your enterprise's data is stored, retrieved, and presented in an efficient way. Data is the single largest asset for any business. All software systems deal with data, and thus its importance cannot be over-emphasized.
An application's data management functions include the four basic operations that are generally carried out on enterprise data:create, retrieve, update,and delete(aka CRUD). Managing data in enterprise systems involves performing the CRUD operations consistently and successfully for a long period of time without having to frequently change the code that actually performs the operations. To put it another way, managing data means developing robust, scalable, and maintainable software systems for successful CRUD operations that are guaranteed to perform consistently through the life of the software.
This article discusses two data management strategies available with the J2EE: Java object serialization and Java Database Connectivity (JDBC). We'll look at the strengths and weaknesses of both of these approaches. No data management strategy is inherently superior or inferior to others. The applicability of a strategy in a particular implementation depends on the scope(the spectrum of activities occurring in the system environment) of the project, the contextof the system (the set of values that drive the runtime of the system/subsystem), and other external factors. However, Java serialization is ill-suited for enterprise systems in which data needs to be organized in a well-defined structure (for example, an RDBMS). We'll first walk through a quick overview of Java object serialization, then walk through some of the more important aspects of JDBC to see how the latter implements crucial features that the former lacks.
This article is not intended to be a comprehensive introduction to either Java object serialization or JDBC. For more information on both technologies, review the Resourcessection.
Java object serialization
Object serializationis the simplest of Java persistence strategies. Object serialization is a process of flattening object graphsto a linear sequence of bytes. Objects graphs are relations realized as a result of the inheritance, association, and aggregation of objects. An object's non-transient instance properties will be written to persistent storage in the form of bytes. The values of instance properties will be the values in the memory at the time serialization is performed. For a Java object to be serializable, it must at minimum implement the java.io.Serializable interface, which has the structure shown below:
package java.io;
public interface Serializable
{}
As you can see, the java.io.Serializableinterface doesn't declare any methods. It is a marker,or tagged,interface. It tells the Java Runtime Environment that the implementing class can be serialized. Listing 1 shows a sample class that implements this interface.
Listing 1. MySerializableObject.java
import java.io.Serializable;
public class MySerializableObject extends MySuperClass implements Serializable
{
private String property1 = null;
private String property2 = null;
public String getProperty1()
{
return property1;
}
public void setProperty1(String val)
{
property1 = val;
}
public String getProperty2()
{
return property2;
}
public void setProperty2(String val)
{
property2 = val;
}
private void writeObject(ObjectOutputStream out)
throws IOException
{
out.writeObject (getProperty1 ());
out.writeObject (getProperty2 ());
}
private void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
setProperty1 ((String) in.readObject ());
setProperty2 ((String) in.readObject ());
}
}
You don't need to implement the writeObject(...)and readObject(...)methods yourself to perform serialization; the Java Runtime Environment will have the default implementation of these methods available. However, you can override these methods and provide your own implementation of how the object state is to be stored.
There are some points about serialization to keep in mind. First, the entire object graph (that is, all parent and referenced classes) will be serialized during serialization. Second, all instance variables of a Serializableclass should themselves beSerializableunless they have been specifically declared transient, or the writeObject(...)and readObject(...)methods have been overridden to serialize only serializable instance variables. If this latter rule is violated, an exception will be thrown at runtime. 0424:17:18
Each succeeding release of J2SE has made small additions to the object serialization system. J2SE 1.4 addedwriteUnshared()and readUnshared()methods to ObjectOutputStreamand ObjectInputStream, respectively. Normally, a serialized stream contains only one serialized instance of any given object and makes back references to it from other objects that share references to it. It is often desirable to serialize an object independent of any references that other objects may maintain to it. The unshared read and write methods allow objects to be serialized as new and unique objects, achieving an effect similar to object cloning but with less overhead.
What's wrong with Java object serialization?
Serialization involves externalizing object graphs from memory to persistent storage (like a hard disk). This involves a lot of I/O overhead. Generally, serialization is not the optimal choice for applications that:
• Manage hundreds of thousands of megabytes of persistent data
• Update serializable objects frequently
Serialization is a bad choice for storing enterprise data because:
• Serialized streams of bytes are readable only by the Java language. This is a major drawback because enterprise systems are generally heterogeneous, with many applications cooperating with each other and working on the same data.
• Object retrieval involves lot of I/O overhead.
• There is no query language for retrieving data from a serialized object graph.
• Serialization has no built-in security mechanism.
• Serialization does not offer any transaction control mechanisms per se, so it cannot be used within applications that need concurrent access without making use of additional APIs.
Java Database Connectivity (JDBC)
Java Database Connectivity(JDBC) is a standard API for interacting with databases using the Java programming language. Call-level interfaces such as JDBC are programming interfaces that allow external access to SQL commands that manipulate and update data in a database. They allow the integration of SQL calls into a general programming environment by providing library routines that interface with the database. In particular, JDBC has a rich collection of routines that make such an interface extremely simple and intuitive.
Over the next few sections, we'll look at the steps involved in interfacing with a database through JDBC. We'll do this with a particular focus on how JDBC compares with Java object serialization as an enterprise data management strategy.
Establish a database connection
Before you do anything else with JDBC, you need to obtain a database driver from a driver vendor and add the library to your class path. Once you've done that, you'll use code like that shown below in your Java program to actually make the connection.
Class.forName();
Java.sql.Connection conn = DriverManager.getConnection();
Java object serialization doesn't require this step, because performing persistence operations using serialization does not require a DBMS. Serialization is a file-based mechanism; so you would need to open an I/O stream to the target file system before you can serialize an object.
Creating JDBC Statements and PreparedStatements
A JDBC Statementobject is used to send your SQL statements to the database management system (DBMS), and should not be confused with an SQL statement. A JDBC Statementobject is associated with an open connection, and not any single SQL statement. You can think of a JDBC Statementobject as a channel sitting on a connection, passing one or more of your SQL statements (which you ask it to execute) to the DBMS.
You need an active connection in order to create a Statementobject. Using the Connectionobject conthat we created previously, the code below does just that.
Statement stmt = con.createStatement();
At this point, a Statementobject exists, but it does not have an SQL statement to pass on to the DBMS.
When a database receives a statement, the database engine first parses that statement and looks for syntax errors. Once the statement is parsed, the database needs to figure out the most efficient way to execute it. This can be computationally quite expensive. The database checks what indexes, if any, can help, or whether it should do a full read of all rows in a table. Databases use statistics on the data to figure out the best way. Once a query planis created, then the database engine can execute it.
It takes CPU power to generate such a plan. Ideally, if we send the same statement to the database twice, then we'd like the database to reuse the access plan for the first statement. We can use a PreparedStatementobject to achieve this.
There's one main feature that distinguishes PreparedStatementfrom its superclass Statement: unlike Statement,PreparedStatementis given an SQL statement when it is created. This SQL statement is then sent to the DBMS right away, where it is compiled. Thus, in effect, a PreparedStatementis associated as a channel with a connection and a compiled SQL statement.
What's the advantage? Well, if you need to use the same query or similar queries with different parameters multiple times, then with a PreparedStatementthe statement can be compiled and optimized by the DBMS just once. Contrast this with a use of a normal Statement, where each use of the same SQL statement requires a compilation all over again.
PreparedStatements are also created with a Connectionmethod. The code below shows how to create a parameterized SQL statement with three input parameters.
PreparedStatement prepareUpdatePrice = con.prepareStatement(
"UPDATE Sells SET price = ? WHERE bar = ? AND beer = ?");
Note that Java serialization does not support a query language like SQL. The only way to access an object property using Java serialization is to deserialize the object and call the getter/accessor methods on the object. Deserializing an entire object can be computationally expensive, especially if your application needs to do it repeatedly throughout the lifetime of your program.
Before we can execute a PreparedStatement, we need to supply values for the parameters. Calling one of the setXXX()methods defined in the PreparedStatementclass can do this. The most often used methods are setInt(), setFloat(), setDouble(), andsetString(). You can set these values before each execution of the prepared statement.
Executing statements and queries
The way you execute SQL statements in JDBC varies depending on the intention of the SQL statement. DDL (data definition language) statements (such as table creation and table alteration statements) and statements that update table contents are all executed using executeUpdate(). Listing 2 contains examples of executeUpdate()statements.
Listing 2. executeUpdate() in action
Statement stmt = con.createStatement();
stmt.executeUpdate("CREATE TABLE Sells " +
"(bar VARCHAR2(40), beer VARCHAR2(40), price REAL)" );
stmt.executeUpdate("INSERT INTO Sells " +
"VALUES ('Bar Of Foo', 'BudLite', 2.00)" );
String sqlString = "CREATE TABLE Bars " +
"(name VARCHAR2(40), address VARCHAR2(80), license INT)" ;
stmt.executeUpdate(sqlString);
We would execute a PreparedStatementby first plugging in the values of the parameters (as seen above), and then invokingexecuteUpdate()on it, as shown below:
int n = prepareUpdatePrice.executeUpdate() ;
In contrast, a queryis expected to return a set of rows as its result, and not change the state of the database. There is a corresponding method called executeQuery(), which returns its results as a ResultSetobject, as shown in Listing 3.
Listing 3. Executing a query
String bar, beer ;
float price ;
ResultSet rs = stmt.executeQuery("SELECT * FROM Sells");
while ( rs.next() ) {
bar = rs.getString("bar");
beer = rs.getString("beer");
price = rs.getFloat("price");
System.out.println(bar + " sells " + beer + " for " + price + " Dollars.");
}
The bag of rows resulting from the query is contained in the variable rs, which is an instance of ResultSet. A set is not of much use to us unless we can access each row and the attributes in each row. The ResultSetprovides a cursor that can be used to access each row in turn. The cursor is initially set just before the first row. Each invocation of the method causes the cursor to move to the next row, returning trueif that row exists or falseif there is no remaining row.
We can use the getXXX()method of the appropriate type to retrieve the attributes of a row. In the previous example, we used thegetString()and getFloat()methods to access the column values. Notice that we provided the name of the column whose value is desired as a parameter to the method; we could have specified the column numbers instead of the column name. The column numbers would be 1 for the first column retrieved, 2 for the second, and so on.
While working with a PreparedStatement, we would execute a query by first plugging in the values of the parameters, and then invoking executeQuery()on it, as shown below:
ResultSet rs = prepareUpdatePrice.executeQuery() ;
Notes on accessing a ResultSet
JDBC also offers you a number of methods to find out where you are in the result set: getRow(), isFirst(), isBeforeFirst(),isLast(), and isAfterLast().
There are also means to give scrollable cursors free access to any row in the result set. By default, cursors scroll forward only and are read only. When creating a Statementfor a Connection, you can change the type of ResultSetto a more flexible scrolling or updatable model, as shown here:
Statement stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery("SELECT * FROM Sells");
The different options for types are TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE, and TYPE_SCROLL_SENSITIVE. You can choose whether the cursor is read-only or updateable using the options CONCUR_READ_ONLYand CONCUR_UPDATABLE. With the default cursor, you can scroll forward using rs.next(). With scrollable cursors you have more options, as shown below:
rs.absolute(3); // moves to the third retrieved row
rs.previous(); // moves back one row in the retrieved result set
rs.relative(2); // moves forward two rows in the retrieved result set
rs.relative(-3); // moves back three rows in the retrieved result set
There are a great many more details to the workings of scrollable cursors. Scrollable cursors, though useful for certain applications, incur an extremely high performance penalty, and should be used with restraint and caution. You can find more information about scrollable ResultSets in the Resourcessection.
There is no serialization counterpart to JDBC's ResultSet. Serialization and JDBC view underlying data from different perspectives. JDBC assumes (most commonly) a relational structure of data; serialization assumes an object graph. The underlying data structures for the two techniques differ significantly. JDBC's Setstructure does not map naturally to the object graph structure of serialization, and vice versa. When a Java object is persisted using serialization semantics, the underlying structure of the data becomes a stream of bytes representing the associations between various internal objects of the core object that has been serialized.
ResultSetnavigation in JDBC is the process of moving from one Setelement to another. This is not possible in the case of object serialization because serialization involves object associations rather than a group of rows packed into an entity set. Thus, Java object serialization does not offer you the ability to access only discrete portions of a data set in this way.
Transactions
JDBC allows SQL statements to be grouped together into a single transaction. Thus, we can ensure the ACID properties using JDBC transactional features.
The Connectionobject performs transaction control. When a connection is created, by default it is in the auto-commit mode. This means that each individual SQL statement is treated as a transaction by itself, and will be committed as soon as its execution finished.
You turn auto-commit mode for an active connection off and on as shown here:
con.setAutoCommit(false) ;
con.setAutoCommit(true) ;
Once auto-commit is off, no SQL statements will be committed (that is, the database will not be permanently updated) until you have explicitly told it to commit by invoking the commit()method. At any point before commit, we may invoke rollback()to roll back the transaction and restore values to the last commit point (before the attempted updates).
We can also set transaction isolation levels as desired. For example, we can set the transaction isolation level toTRANSACTION_READ_COMMITTED, which will not allow a value to be accessed until after it has been committed, and which will forbid dirty reads. There are five such values for isolation levels provided in the Connectioninterface. By default, the isolation level is serializable. JDBC allows us to find out what transaction isolation level the database is set to (using the ConnectionmethodgetTransactionIsolation()) and set the appropriate level (using the Connectionmethod setTransactionIsolation()).
Rollback will usually be used in combination with the Java language's exception handling ability. Such a combination provides an excellent and easy mechanism for handling data integrity. We'll study error handling using JDBC in the next section.
Note that Java object serialization does not have direct support for transaction management. If you're using serialization, you'll need to fall back on other APIs, such as JTA, for achieving this effect. However, to achieve the effect of transaction isolation, you may choose to synchronize the serialized object when performing an update on it, as shown here:
Synchronized(my_deserialized_object) {
//Perform the updates etc...
}
Handling errors with exceptions
Errors always occur in software programs. Often, database programs are critical applications, and it is imperative that errors be caught and handled gracefully. Programs should recover and leave the database in a consistent state. Rollbacks used in conjunction with Java exception handlers are a clean way of achieving such a requirement.
The client (program) accessing a server (database) needs to be aware of any errors returned from the server. JDBC gives access to such information by providing two levels of error conditions: SQLExceptionand SQLWarning. SQLExceptions are Java exceptions, which, if not handled, will terminate the application. SQLWarnings are subclasses of SQLException, but they represent nonfatal errors or unexpected conditions, and as such, can be ignored.
In Java code, statements that are expected to throw an exception or a warning are enclosed in a tryblock. If a statement in thetryblock throws an exception or a warning, it can be caught in one of the corresponding catchstatements. Each catch statement specifies the exceptions that it is ready to catch.
Alternatively, if your data types are correct, an exception might be thrown if your database size goes over its space quota and is unable to construct a new table. SQLWarnings can be retrieved from Connection, Statement, and ResultSetobjects. Each only stores the most recent SQLWarning. So if you execute another statement through your Statementobject, for instance, any earlier warnings will be discarded. Listing 4 illustrates the use of SQLWarnings.
Listing 4. SQLWarnings in action
ResultSet rs = stmt.executeQuery("SELECT bar FROM Sells") ;
SQLWarning warn = stmt.getWarnings() ;
if (warn != null)
System.out.println("Message: " + warn.getMessage()) ;
SQLWarning warning = rs.getWarnings() ;
if (warning != null)
warning = warning.getNextWarning() ;
if (warning != null)
System.out.println("Message: " + warn.getMessage()) ;
SQLWarnings are actually somewhat rarer than SQLExceptions. The most common is a DataTruncationwarning, which indicates that there was a problem while reading or writing data from the database.
Java does not provide special exception classes to be used with serialization. Most of the exceptions that occur when serialization is used are related the I/O operations performed, so the I/O exception classes will suffice in those cases.
Batch processing
JDBC 2.0 provides a powerful API for batch processing. Batch processing allows for piling up a group of SQL statements and sending them for processing in one go. A typical batch processing scenario might involve a banking application that updates a number of accounts every quarter. Batch processing is a powerful feature in that it reduces the number of round trips from Java code to a database.
The Statementinterface provides an addBatch(String)method for adding an SQL statement to a batch. Once you've added all your SQL statements to the batch, you can execute them in one go using the executeBatch()method.
The executeBatch()method then executes the SQL statements and returns an array of intvalues. This array contains the number of rows affected by each statement. Putting a SELECTstatement or other ResultSet-returning SQL in a batch will result in aSQLException.
A simple example of batch processing with java.sql.Statementis shown in Listing 5.
Listing 5. Batch processing in action
Statement stmt = conn.createStatement();
stmt.insert("DELETE FROM Users");
stmt.insert("INSERT INTO Users VALUES('rod', 37, 'circle')");
stmt.insert("INSERT INTO Users VALUES('jane', 33, 'triangle')");
stmt.insert("INSERT INTO Users VALUES('freddy', 29, 'square')");
int[] counts = stmt.executeBatch();
Batch processing is a nice way to handle SQL code when you don't know how many times a particular statement will run. For instance, if we tried to insert 100 records into a database without batching, the performance may be affected. If we wrote a script to add 10,000 records, things could get nasty. Adding batch processing helps to improve the performance, and in the latter case even improves the readability of the code.
Java object serialization does not support batch processing. Typically, serialization involves working on the extent (the association graph) of an object, so batch processing doesn't make sense in such a case. Batch processing thus affords you a flexibility in terms of the timing and grouping of data updates that is not necessarily available with serialization.
Calling a stored procedure from Java code
A stored procedureis a group of SQL statements that form a logical unit and perform a particular task. Stored procedures are used to encapsulate a set of operations or queries that will execute on a database server. Stored procedures are compiled and stored in the database server. So each time a stored procedure in invoked, the DBMS will reuse the compiled binary, and hence the execution will be faster.
JDBC allows you to call a database stored procedure from an Java application. The first step is to create aCallableStatementobject. As with Statementand PreparedStatementobjects, this is done with an open Connectionobject. ACallableStatementobject contains a call to a stored procedure; it does not contain the stored procedure itself. The first line of code in Listing 6 creates a call to the stored procedure SHOW_ACCOUNTusing the connection con. The part that is enclosed in curly braces is the escape syntax for stored procedures. When the driver encounters {call SHOW_ACCOUNT}, it will translate this escape syntax into the native SQL used by the database to call the stored procedure named SHOW_ACCOUNT.
Listing 6. A stored procedure in action
CallableStatement cs = con.prepareCall("{call SHOW_ACCOUNT(?)}");
cs.setInt(1,myaccountnumber);
ResultSet rs = cs.executeQuery();
Assume the stored procedure SHOW_ACCOUNTin Sybase has code shown in Listing 7.
Listing 7. SHOW_ACCOUNT stored procedure
CREATE PROCEDURE SHOW_ACCOUNT (@Acc int)
AS
BEGIN
Select balance from USER_ACCOUNTS where Account_no = @Acc
END
The ResultSet rswill look like this:
balance
----------------
12000.95
Note that the method used to execute csis executeQuery(), because cscalls a stored procedure that contains one query and thus produces one result set. If the procedure had contained one update or one DDL statement, the method executeUpdate()would have been the one to use. It is sometimes the case, however, that a stored procedure contains more than one SQL statement, in which case it will produce more than one result set, more than one update count, or some combination of result sets and update counts. In such a case, the method execute()should be used to execute the CallableStatement.
The class CallableStatementis a subclass of PreparedStatement, so a CallableStatementobject can take input parameters just as a PreparedStatementobject can. In addition, a CallableStatementobject can take output parameters or parameters that are for both input and output. INOUTparameters and the execute()method are rarely used. For handling OUTparameters, we need to register an OUTparameter with the stored procedure using the method registerOutParameter(int, int).
As an example, let's assume that the GET_ACCOUNTprocedure contains the code in Listing 8.
Listing 8. GET_ACCOUNT
CREATE PROCEDURE GET_ACCOUNT (@Acc int, @balance float OUTPUT)
AS
BEGIN
Select @balance = balance from USER_ACCOUNTS where Account_no = @Acc
END
In this case, the parameter balancehas been declared as an OUTparameter. Now the JDBC code for calling the procedure will be as in Listing 9.
Listing 9. JDBC code for calling a stored procedure
CallableStatement csmt = con.prepareCall("{GET_ACCOUNT(?,?)");
csmt.setInt(1,youraccountnumber);
csmt.registerOutParamter(2,java.sql.Types.FLOAT);
csmt.execute();
When you're using Java serialization, you do not need to access and external system like a DBMS. In other words, serialization is a pure Java language phenomenon, so it doesn't involve executing a compiled code residing in an external environment. Hence, there is no counterpart for JDBC's CallableStatementobject in serialization. This means that you can't offload data processing to external systems or components that might be better suited for it.
Wrapping up
We hope you'll agree, after reading this article, that JDBC is a much better approach to data management and persistence than Java object serialization.
JDBC is an excellent API for accessing data stores. The best thing about JDBC is that it provides a single set of APIs for accessing a variety of data sources. The user needs to learn only one set of APIs to access any data source, be it relational, hierarchical, or any other format. All that is needed is a JDBC driver to connect to the target data source. JDBC does a great job of wrapping all technical details inside an implementation wrapper and freeing the programmer from vendor-specific hassles.
Table 1 compares the various features of JDBC and Java object serialization.
Table 1. JDBC vs. Java serialization
Object serialization JDBC
Data management Uses the filesystem for storing the serialized object forms. Doesn't include a special data management system. The serialized objects (stored in flat files) are generally managed by the underlying OS in its own particular way. Uses an EAI/database for storing data. The EAI or database will have a special Database Management System (DBMS) to manage the data in the data source. JDBC works as an interface between the JVM and the DBMS to send requests to the DBMS. JDBC itself doesn't have any data management functions.
Data structure The underlying data structure is an object graph. Serialization writes the state of a Java object to a filesystem. Underlying data structure can be relational, hierarchical, or a network. But the logic view of the data is most commonly a table.
Data definition The data definition involves creating a serializable object and persisting the object using serialization semantics. The data definition involves creating necessary tables in the target data store and providing clear definition of domain-level relationships between entity sets. This is generally done using the software provided by the target DBMS.
Data retrieval Retrieval involves deserializing the object and reading the object properties using accessor methods. DBMS provides a special data sub-language for data retrieval. The statements written in the data sublanguage will be passed to the target data source through the JDBC API. It is the responsibility of the DBMS to validate, execute and return the results of the statements.
Security There is no well-defined security mechanism available. However, the underlying OS can provide security to the serialized files. A DBMS provides a comprehensive set of security features. It does the job of authentication and authorization. The JDBC API needs to send the credentials to the target DBMS before it can access or manipulate the data on the DBMS.
Transactions There is no specific transaction control mechanism available. Transactions can be maintained programmatically by using other J2EE APIs, such as JTA or JTS. Sophisticated transaction management is provided by the DBMS. The JDBC API provides useful methods to commit and roll back transactions.
Concurrency control There is no specific concurrency control mechanism available. However, by using the synchronization techniques in the Java language, you can achieve the effect of concurrency control. Multiple levels of transaction isolation are provided by the DBMS. We can choose a particular level of isolation using JDBC API methods.
Java object serialization and JDBC are two of many data persistence mechanisms available in the Java technology sphere. Serialization is best suited when data needs to be shared in a Java language-specific format among multiple JVMs (as done in RMI's pass-by-value mechanism). However, Java serialization is ill-suited for enterprise systems where data needs to be organized in a well-defined structure. In such enterprise systems, data needs to be shared between multiple systems and subsystems that may not all be Java language compatible. In such cases, object serialization does not work at all.
JDBC provides a common API for accessing heterogeneous data stores. It acts as the glue between the JVM and the target DBMS. It provides a programmatic way of accessing data stores and maintaining enterprise data using the Java platform. However, all the code required for performing CRUD operations needs to be written by the developer.
To get the best out of JDBC in enterprise environments, architects need to analyze the data in their enterprise and evolve a framework for data persistence. Since the mechanism for persisting data using JDBC is not relevant to the business problem the system intends to address, it is strongly recommended that the data persistence layer be separated from application business logic. Design patterns will greatly help in designing such framework.