javax.sql.

* Package

‡ Provides the API for server side data source access and processing. ‡ This package supplements the java.sql.* package and, as of the version 1.4 release, is included in the Java Platform, Standard Edition. ‡ It remains an essential part of the Java Platform, Enterprise Edition.

‡ The javax.sql package provides for the following: ‡ The DataSource interface as an alternative to the DriverManager for establishing a connection with a data source. ‡ Connection pooling ‡ Distributed transactions ‡ Rowsets

‡ Applications use the DataSource and RowSet APIs directly, but the connection pooling and distributed transaction APIs are used internally by the middle-tier infrastructure.

DataSource Object
‡ These are the main advantages of using a DataSource object to make a connection: ‡ Changes can be made to a data source's properties, which means that it is not necessary to make changes in application code when something about the data source or driver changes. ‡ Connection and Statement pooling and distributed transactions are available through a DataSource object that is implemented to work with the middle-tier infrastructure. ‡ Connections made through the DriverManager do not have connection and statement pooling or distributed transaction capabilities.

‡ Driver vendors provide DataSource implementations. ‡ A particular DataSource object represents a particular physical data source, and each connection the DataSource object creates is a connection to that physical data source.

‡ A logical name for the data source is registered with a naming service that uses the Java Naming and Directory Interface (JNDI) API, usually by a system administrator or someone performing the duties of a system administrator.

‡ An application can retrieve the DataSource object it wants by doing a lookup on the logical name that has been registered for it. ‡ The application can then use the DataSource object to create a connection to the physical data source it represents.

Java Naming and Directory Interface (JNDI)
‡ Naming and directory services play a vital role in intranets and the Internet by providing networkwide sharing of a variety of information about users, machines, networks, services, and applications. ‡ JNDI is an API specified in Java technology that provides naming and directory functionality to applications written in the Java programming language.

Java Naming and Directory Interface (JNDI)

‡ Using JNDI, applications based on Java technology can store and retrieve named Java objects of any type. ‡ In addition, JNDI provides methods for performing standard directory operations, such as associating attributes with objects and searching for objects using their attributes.

Java Naming and Directory Interface (JNDI)
‡ It enables applications to access different, possibly multiple, naming and directory services using a common API. ‡ Different naming and directory service providers can be plugged in seamlessly behind this common API.

Creating and Registering a DataSource Object
VendorDataSource vds = new VendorDataSource(); vds.setServerName("my_database_server"); vds.setDatabaseName("my_database"); vds.setDescription("the data source for inventory and personnel"); Context ctx = new InitialContext(); ctx.bind("jdbc/AcmeDB", vds);

‡ The first four lines represent API from a vendor's class VendorDataSource, an implementation of the javax.sql.DataSource interface. ‡ They create a DataSource object, vds, and set its serverName, databaseName, and description properties. ‡ The fifth and sixth lines use JNDI API to register vds with a JNDI naming service.

‡ The fifth line calls the default InitialContext constructor to create a Java object that references the initial JNDI naming context. ‡ System properties, which are not shown here, tell JNDI which naming service provider to use. ‡ The last line associates vds with a logical name for the data source that vds represents.

Connecting to a Data Source
Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup("jdbc/AcmeDB"); Connection con = ds.getConnection("genius", "abracadabra");

Advantages of Using JNDI
‡ There are major advantages to connecting to a data source using a DataSource object registered with a JNDI naming service rather than using the DriverManager facility. ‡ The first is that it makes code more portable. ‡ With the DriverManager, the name of a JDBC driver class, which usually identifies a particular driver vendor, is included in application code. This makes the application specific to that vendor's driver product and thus non-portable.

‡ Another advantage is that it makes code much easier to maintain. If any of the necessary information about the data source changes, only the relevant DataSource properties need to be modified, not every application that connects to that data source. ‡ For example, if a database is moved to a different server and uses a different port number, only the DataSource object's serverName and portNumber properties need to be updated.

‡ Yet another advantage is that applications using a DataSource object to get a connection will automatically benefit from connection pooling if the DataSource class has been implemented to support connection pooling. ‡ Likewise, an application will automatically be able to use distributed transactions if the DataSource class has been implemented to support them.

‡ What is LDAP? ‡ LDAP, Lightweight Directory Access Protocol, is an Internet protocol that email and other programs use to look up information from a server

Connection Pooling
‡ Originally, JDBC 1.0 defined the Java APIs for access to relational databases. ‡ With the introduction of JDBC 2.0, the APIs were split into two parts: ‡ The JDBC 2.0 Core API ‡ This contains evolutionary improvements but has been kept small and focused like the JDBC 1.0 API in order to promote ease of use. Code written for the 1.0 API continues to work with the 2.0 API. The 2.0 API classes remain in the java.sql package.

‡ The JDBC 2.0 Optional Package API ‡ This supports integration with additional Java standards, including JNDI (Java Naming and Directory Interface), JTA (Java Transaction API), and EJB (Enterprise JavaBeans), as well as providing support for connection pooling and Java beans.

‡ Connection pooling is the maintenance of a group of database connections for reuse by applications on an application server. ‡ Connection pooling allows the idle connection to be used by some other thread to do useful work. ‡ In practice, a thread requests a connection from the pool. ‡ When the thread is finished using the connection, it returns it to the pool, so that it may be used by any other threads that want to use it.

Benefits of Connection Pooling
‡ Reduced connection creation time: JDBC driver overhead can be avoided if connections are "recycled.³ ‡ Simplified programming model: Allowing you to use straight-forward JDBC programming techniques.

‡ Controlled resource usage : Connection pools can be tuned to maximize performance, while keeping resource utilization below.

Connection Pooling Implementation
‡ Generally, you configure a connection pool in your application server configuration files, and access it via the Java Naming and Directory Interface (JNDI). ‡ Connection pooling is totally transparent. It is done automatically in the middle tier of a J2EE configuration, so from an application's viewpoint, no change in code is required.

‡ An application simply uses the DataSource.getConnection method to get the pooled connection and uses it the same way it uses any Connection object. ‡ The classes and interfaces used for connection pooling are: ‡ ConnectionPoolDataSource ‡ PooledConnection ‡ ConnectionEvent ‡ ConnectionEventListener

‡ The connection pool manager, a facility in the middle tier of a three-tier architecture, uses these classes and interfaces behind the scenes.

‡ Application code to initialize a pooling DataSource and add it to JNDI might look like this:
Jdbc3PoolingDataSource source = new Jdbc3PoolingDataSource(); source.setDataSourceName("A Data Source"); source.setServerName("localhost"); source.setDatabaseName("test"); source.setUser("testuser"); source.setPassword("testpassword"); source.setMaxConnections(10); new InitialContext().rebind("DataSource", source);

‡ Then code to use a connection from the pool might look like this:
Connection con = null; try { DataSource source = (DataSource) new InitialContext().lookup("DataSource"); con = source.getConnection(); // use connection } catch(SQLException e) { // log error } catch(NamingException e) { // DataSource wasn't found in JNDI } finally { if(con != null) { try {con.close();} catch(SQLException e) {} } }

‡ Note that it is critical that the connections are closed, or else the pool will "leak" connections, and eventually lock all the clients out.

Distributed Transactions
‡ This gives an application the ability to involve data sources on multiple servers in a single transaction. ‡ The classes and interfaces used for distributed transactions are: ‡ XADataSource ‡ XAConnection
‡ These interfaces are used by the transaction manager; an application does not use them directly.

Distributed Transactions
‡ A transaction manager in the middle tier handles everything transparently. ‡ An application cannot call the methods Connection.commit or Connection.rollback, and it cannot set the connection to be in auto-commit mode (that is, it cannot call Connection.setAutoCommit(true)).

Distributed Transactions
‡ An application does not need to do anything special to participate in a distributed transaction. ‡ It simply creates connections to the data sources it wants to use via the DataSource.getConnection method, just as it normally does.

Distributed Transactions
‡ The transaction manager manages the transaction behind the scenes. ‡ The XADataSource interface creates XAConnection objects, and each XAConnection object creates an XAResource object that the transaction manager uses to manage the connection.

RowSets
‡ A RowSet object contains a set of rows from a result set or some other source of tabular data, like a file or spreadsheet. ‡ Because a RowSet object follows the JavaBeans model for properties and event notification, it is a JavaBeans component that can be combined with other components in an application. ‡ Rowsets make it easy to send tabular data over a network.

RowSets (Contd..)
‡ Two broad categories, rowsets that are connected and those that are disconneced. ‡ A disconnected rowset gets a connection to a data source in order to fill itself with data or to propagate changes in data back to the data source, but most of the time it does not have a connection open. ‡ A disconnected rowset stores its data in memory.

RowSets (Contd..)
‡ A connected rowset, by contrast, opens a connection and keeps it open for as long as the rowset is in use.

Types of RowSets
‡ A CachedRowSet class²a disconnected rowset that caches its data in memory; not suitable for very large data sets, but an ideal way to provide thin Java clients, such as a Personal Digital Assistant (PDA) or Network Computer (NC), with tabular data. ‡ A JDBCRowSet class²a connected rowset that serves mainly as a thin wrapper around a ResultSet object to make a JDBC driver look like a JavaBeans component.

Types of RowSets (Contd..)
‡ A WebRowSet class²a connected rowset that uses the HTTP protocol internally to talk to a Java servlet that provides data access; used to make it possible for thin web clients to retrieve and possibly update a set of rows.

CachedRowSet Example
‡ The code for creating a CachedRowSet object simply uses the default constructor.
CachedRowSet crset = new CachedRowSet(); crset.setCommand("SELECT * FROM COFFEES"); crset.setDataSourceName("jdbc/coffeesDB"); crset.setUsername("juanvaldez"); crset.setPassword("espresso"); crset.execute(); while (crset.next()) { System.out.println(crset.getString("COF_NAME")); }

JdbcRowSet Example
JdbcRowSet jdbcRs2 = new JdbcRowSetImpl(); jdbcRs.setUsername("hardy"); jdbcRs.setPassword("oursecret"); jdbcRs.setUrl("jdbc:mySubprotocol:mySubname"); jdbcRs.setCommand("select * from COFFEES"); jdbcRs.execute();

JdbcRowSet Example (Contd..)
while (jdbcRs.next()) { String name = jdbcRs.getString("COF_NAME"); String price = jdbcRs.getString("PRICE"); System.out.println(name); System.out.println(price); }

WebRowSet
‡ A WebRowSet object is very special because in addition to offering all of the capabilities of a CachedRowSet object, it can write itself as an XML document and can also read that XML document to convert itself back to a WebRowSet object. ‡ Because XML is the language through which disparate enterprises can communicate with each other, it has become the standard for Web Services communication. ‡ As a consequence, a WebRowSet object fills a real need by making it easy for Web Services to send and receive data from a database in the form of an XML document.

WebRowSet Example
WebRowSet priceList = new WebRowSetImpl(); priceList.setCommand("SELECT COF_NAME, PRICE FROM COFFEES"); priceList.setURL("jdbc:mySubprotocol:myDa tabase"); priceList.setUsername("myUsername"); priceList.setPassword("myPassword"); priceList.execute();

Writing and Reading a WebRowSet Object to XML
‡ The method writeXML writes the WebRowSet object that invoked it as an XML document. ‡ It writes this XML document to the stream that pass to it.

Writing and Reading a WebRowSet Object to XML (Contd..)
‡ The stream can be an OutputStream object, such as a FileOutputStream object, or a Writer object, such as a FileWriter object.
‡ If you pass the method writeXml an OutputStream object, you will write in bytes, which can handle all types of data; if you pass it a Writer object, you will write in characters.

Writing and Reading a WebRowSet Object to XML (Contd..)
‡ The following code demonstrates writing the WebRowSet object priceList as an XML document to the FileOutputStream object oStream. java.io.FileOutputStream oStream = new java.io.FileOutputStream("priceList.xml"); priceList.writeXml(oStream);

Writing and Reading a WebRowSet Object to XML (Contd..)
‡ The following code writes the XML document representing priceList to the FileWriter object writer. java.io.FileWriter writer = new java.io.FileWriter("priceList.xml"); priceList.writeXml(writer);

Writing and Reading a WebRowSet Object to XML (Contd..) ‡ The method readXml parses an XML document in order to construct the WebRowSet object the XML document describes. Analogous to the method writeXml, you can pass readXml an InputStream object or a Reader object from which to read the XML document.

Writing and Reading a WebRowSet Object to XML (Contd..) InputStream object example :java.io.FileInputStream iStream = new java.io.FileInputStream("priceList.xml"); priceList.readXml(iStream); Reader object Example :java.io.FileReader reader = new java.io.FileReader("priceList.xml"); priceList.readXml(reader);