| |
Package Name | Comment | java.sql |
Provides the API for accessing and processing data stored in a
data source (usually a relational database) using the
JavaTM programming language.
This API includes a framework whereby different
drivers can be installed dynamically to access different data sources.
Although the JDBCTM API is mainly geared
to passing SQL statements to a database, it provides for reading and
writing data from any data source with a tabular format.
The reader/writer facility, available through the
javax.sql.RowSet group of interfaces, can be customized to
use and update data from a spread sheet, flat file, or any other tabular
data source.
What the JDBCTM 4.0 API Includes
The JDBCTM 4.0 API includes both
the java.sql package, referred to as the JDBC core API,
and the javax.sql package, referred to as the JDBC Optional
Package API. This complete JDBC API
is included in the JavaTM
Standard Edition (Java SETM), version 6.
The javax.sql package extends the functionality of the JDBC API
from a client-side API to a server-side API, and it is an essential part
of the JavaTM Enterprise Edition
(Java EETM) technology.
Versions
The JDBC 4.0 API incorporates all of the previous JDBC API versions:
- The JDBC 3.0 API
- The JDBC 2.1 core API
- The JDBC 2.0 Optional Package API
(Note that the JDBC 2.1 core API and the JDBC 2.0 Optional Package
API together are referred to as the JDBC 2.0 API.)
- The JDBC 1.2 API
- The JDBC 1.0 API
Classes, interfaces, methods, fields, constructors, and exceptions
have the following "since" tags that indicate when they were introduced
into the Java platform. When these "since" tags are used in
JavadocTM comments for the JDBC API,
they indicate the following:
- Since 1.6 -- new in the JDBC 4.0 API and part of the Java SE platform,
version 6
- Since 1.4 -- new in the JDBC 3.0 API and part of the J2SE platform,
version 1.4
- Since 1.2 -- new in the JDBC 2.0 API and part of the J2SE platform,
version 1.2
- Since 1.1 or no "since" tag -- in the original JDBC 1.0 API and part of
the JDKTM, version 1.1
NOTE: Many of the new features are optional; consequently, there is
some variation in drivers and the features they support. Always
check your driver's documentation to see whether it supports a feature before
you try to use it.
NOTE: The class SQLPermission was added in the
JavaTM 2 SDK, Standard Edition,
version 1.3 release. This class is used to prevent unauthorized
access to the logging stream associated with the DriverManager ,
which may contain information such as table names, column data, and so on.
What the java.sql Package Contains
The java.sql package contains API for the following:
- Making a connection with a database via the
DriverManager facility
DriverManager class -- makes a connection with a driver
SQLPermission class -- provides permission when code
running within a Security Manager, such as an applet,
attempts to set up a logging stream through the
DriverManager
Driver interface -- provides the API for registering
and connecting drivers based on JDBC technology ("JDBC drivers");
generally used only by the DriverManager class
DriverPropertyInfo class -- provides properties for a
JDBC driver; not used by the general user
- Sending SQL statements to a database
Statement -- used to send basic SQL statements
PreparedStatement -- used to send prepared statements or
basic SQL statements (derived from Statement )
CallableStatement -- used to call database stored
procedures (derived from PreparedStatement )
Connection interface -- provides methods for creating
statements and managing connections and their properties
Savepoint -- provides savepoints in a transaction
- Retrieving and updating the results of a query
- Standard mappings for SQL types to classes and interfaces in the
Java programming language
Array interface -- mapping for SQL ARRAY
Blob interface -- mapping for SQL BLOB
Clob interface -- mapping for SQL CLOB
Date class -- mapping for SQL DATE
NClob interface -- mapping for SQL NCLOB
Ref interface -- mapping for SQL REF
RowId interface -- mapping for SQL ROWID
Struct interface -- mapping for SQL STRUCT
SQLXML interface -- mapping for SQL XML
Time class -- mapping for SQL TIME
Timestamp class -- mapping for SQL TIMESTAMP
Types class -- provides constants for SQL types
- Custom mapping an SQL user-defined type (UDT) to a class in the
Java programming language
SQLData interface -- specifies the mapping of
a UDT to an instance of this class
SQLInput interface -- provides methods for reading
UDT attributes from a stream
SQLOutput interface -- provides methods for writing
UDT attributes back to a stream
- Metadata
DatabaseMetaData interface -- provides information
about the database
ResultSetMetaData interface -- provides information
about the columns of a ResultSet object
ParameterMetaData interface -- provides information
about the parameters to PreparedStatement commands
- Exceptions
SQLException -- thrown by most methods when there
is a problem accessing data and by some methods for other reasons
SQLWarning -- thrown to indicate a warning
DataTruncation -- thrown to indicate that data may have
been truncated
BatchUpdateException -- thrown to indicate that not all
commands in a batch update executed successfully
java.sql and javax.sql Features Introduced in the JDBC 4.0 API
- auto java.sql.Driver discovery -- no longer need to load a
java.sql.Driver class via Class.forName
- National Character Set support added
- Support added for the SQL:2003 XML data type
- SQLException enhancements -- Added support for cause chaining; New SQLExceptions
added for common SQLState class value codes
- Enhanced Blob/Clob functionality -- Support provided to create and free a Blob/Clob instance
as well as additional methods added to improve accessiblity
- Support added for accessing a SQL ROWID
- Support added to allow a JDBC application to access an instance of a JDBC resource
that has been wrapped by a vendor, usually in an application server or connection
pooling environment.
- Availability to be notfied when a
PreparedStatement that is associated
with a PooledConnection has been closed or the driver determines is invalid
java.sql and javax.sql Features Introduced in the JDBC 3.0 API
- Pooled statements -- reuse of statements associated with a pooled
connection
- Savepoints -- allow a transaction to be rolled back to a designated
savepoint
- Properties defined for
ConnectionPoolDataSource -- specify
how connections are to be pooled
- Metadata for parameters of a
PreparedStatement object
- Ability to retrieve values from automatically generated columns
- Ability to have multiple
ResultSet objects
returned from CallableStatement objects open at the
same time
- Ability to identify parameters to
CallableStatement
objects by name as well as by index
ResultSet holdability -- ability to specify whether cursors
should be held open or closed at the end of a transaction
- Ability to retrieve and update the SQL structured type instance that a
Ref object references
- Ability to programmatically update
BLOB ,
CLOB , ARRAY , and REF values.
- Addition of the
java.sql.Types.DATALINK data type --
allows JDBC drivers access to objects stored outside a data source
- Addition of metadata for retrieving SQL type hierarchies
java.sql Features Introduced in the JDBC 2.1 Core API
- Scrollable result sets--using new methods in the
ResultSet
interface that allow the cursor to be moved to a particular row or to a
position relative to its current position
- Batch updates
- Programmatic updates--using
ResultSet updater methods
- New data types--interfaces mapping the SQL3 data types
- Custom mapping of user-defined types (UDTs)
- Miscellaneous features, including performance hints, the use of character
streams, full precision for
java.math.BigDecimal values,
additional security, and
support for time zones in date, time, and timestamp values.
javax.sql Features Introduced in the JDBC 2.0 Optional
Package API
- The
DataSource interface as a means of making a connection. The
Java Naming and Directory InterfaceTM
(JNDI) is used for registering a DataSource object with a
naming service and also for retrieving it.
- Pooled connections -- allowing connections to be used and reused
- Distributed transactions -- allowing a transaction to span diverse
DBMS servers
RowSet technology -- providing a convenient means of
handling and passing data
Custom Mapping of UDTs
A user-defined type (UDT) defined in SQL can be mapped to a class in the Java
programming language. An SQL structured type or an SQL DISTINCT
type are the UDTs that may be custom mapped. The following three
steps set up a custom mapping:
- Defining the SQL structured type or
DISTINCT type in SQL
- Defining the class in the Java programming language to which the
SQL UDT will be mapped. This class must implement the
SQLData interface.
- Making an entry in a
Connection object's type map
that contains two things:
- the fully-qualified SQL name of the UDT
- the
Class object for the class that implements the
SQLData interface
When these are in place for a UDT, calling the methods
ResultSet.getObject or CallableStatement.getObject
on that UDT will automatically retrieve the custom mapping for it. Also, the
PreparedStatement.setObject method will automatically map the
object back to its SQL type to store it in the data source.
Package Specification
Related Documentation
@since 1.1
| javax.sql |
Provides the API for server side data source access and processing from
the JavaTM programming language.
This package supplements the java.sql
package and, as of the version 1.4 release, is included in the
Java Platform, Standard Edition
(Java SETM).
It remains an essential part of the Java Platform, Enterprise Edition
(Java EETM).
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 and Statement 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.
Using a DataSource Object to Make a Connection
The javax.sql package provides the preferred
way to make a connection with a data source. The DriverManager
class, the original mechanism, is still valid, and code using it will
continue to run. However, the newer DataSource mechanism
is preferred because it offers many advantages over the
DriverManager mechanism.
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 InterfaceTM
(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.
A DataSource object can be implemented to work with the
middle tier infrastructure so that the connections it produces will be
pooled for reuse. An application that uses such a DataSource
implementation will automatically get a connection that participates in
connection pooling.
A DataSource object can also be implemented to work with the
middle tier infrastructure so that the connections it produces can be
used for distributed transactions without any special coding.
Connection Pooling and Statement Pooling
Connections made via a DataSource
object that is implemented to work with a middle tier connection pool manager
will participate in connection pooling. This can improve performance
dramatically because creating new connections is very expensive.
Connection pooling allows a connection to be used and reused,
thus cutting down substantially on the number of new connections
that need to be created.
Connection pooling is totally transparent. It is done automatically
in the middle tier of a Java EE 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
StatementEvent
StatementEventListener
The connection pool manager, a facility in the middle tier of
a three-tier architecture, uses these classes and interfaces
behind the scenes. When a ConnectionPoolDataSource object
is called on to create a PooledConnection object, the
connection pool manager will register as a ConnectionEventListener
object with the new PooledConnection object. When the connection
is closed or there is an error, the connection pool manager (being a listener)
gets a notification that includes a ConnectionEvent object.
If the connection pool manager supports Statement pooling, for
PreparedStatements , which can be determined by invoking the method
DatabaseMetaData.supportsStatementPooling , the
connection pool manager will register as a StatementEventListener
object with the new PooledConnection object. When the
PreparedStatement is closed or there is an error, the connection
pool manager (being a listener)
gets a notification that includes a StatementEvent object.
Distributed Transactions
As with pooled connections, connections made via a DataSource
object that is implemented to work with the middle tier infrastructure
may participate in 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.
The XAConnection interface is derived from the
PooledConnection interface, so what applies to a pooled connection
also applies to a connection that is part of a distributed transaction.
A transaction manager in the middle tier handles everything transparently.
The only change in application code is that an application cannot do anything
that would interfere with the transaction manager's handling of the transaction.
Specifically, 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) ).
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.
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
The RowSet interface works with various other classes and
interfaces behind the scenes. These can be grouped into three categories.
- Event Notification
RowSetListener
A RowSet object is a JavaBeansTM
component because it has properties and participates in the JavaBeans
event notification mechanism. The RowSetListener interface
is implemented by a component that wants to be notified about events that
occur to a particular RowSet object. Such a component registers
itself as a listener with a rowset via the RowSet.addRowSetListener
method.
When the RowSet object changes one of its rows, changes all of
it rows, or moves its cursor, it also notifies each listener that is registered
with it. The listener reacts by carrying out its implementation of the
notification method called on it.
RowSetEvent
As part of its internal notification process, a RowSet object
creates an instance of RowSetEvent and passes it to the listener.
The listener can use this RowSetEvent object to find out which rowset
had the event.
- Metadata
RowSetMetaData
This interface, derived from the
ResultSetMetaData interface, provides information about
the columns in a RowSet object. An application can use
RowSetMetaData methods to find out how many columns the
rowset contains and what kind of data each column can contain.
The RowSetMetaData interface provides methods for
setting the information about columns, but an application would not
normally use these methods. When an application calls the RowSet
method execute , the RowSet object will contain
a new set of rows, and its RowSetMetaData object will have been
internally updated to contain information about the new columns.
- The Reader/Writer Facility
A RowSet object that implements the RowSetInternal
interface can call on the RowSetReader object associated with it
to populate itself with data. It can also call on the RowSetWriter
object associated with it to write any changes to its rows back to the
data source from which it originally got the rows.
A rowset that remains connected to its data source does not need to use a
reader and writer because it can simply operate on the data source directly.
RowSetInternal
By implementing the RowSetInternal interface, a
RowSet object gets access to
its internal state and is able to call on its reader and writer. A rowset
keeps track of the values in its current rows and of the values that immediately
preceded the current ones, referred to as the original values. A rowset
also keeps track of (1) the parameters that have been set for its command and
(2) the connection that was passed to it, if any. A rowset uses the
RowSetInternal methods behind the scenes to get access to
this information. An application does not normally invoke these methods directly.
RowSetReader
A disconnected RowSet object that has implemented the
RowSetInternal interface can call on its reader (the
RowSetReader object associated with it) to populate it with
data. When an application calls the RowSet.execute method,
that method calls on the rowset's reader to do much of the work. Implementations
can vary widely, but generally a reader makes a connection to the data source,
reads data from the data source and populates the rowset with it, and closes
the connection. A reader may also update the RowSetMetaData object
for its rowset. The rowset's internal state is also updated, either by the
reader or directly by the method RowSet.execute .
RowSetWriter
A disconnected RowSet object that has implemented the
RowSetInternal interface can call on its writer (the
RowSetWriter object associated with it) to write changes
back to the underlying data source. Implementations may vary widely, but
generally, a writer will do the following:
- Make a connection to the data source
- Check to see whether there is a conflict, that is, whether
a value that has been changed in the rowset has also been changed
in the data source
- Write the new values to the data source if there is no conflict
- Close the connection
The RowSet interface may be implemented in any number of
ways, and anyone may write an implementation. Developers are encouraged
to use their imaginations in coming up with new ways to use rowsets.
IMPORTANT NOTE: Code that uses API marked "Since 1.6" must be run using a
JDBC technology driver that implements the JDBC 4.0 API.
You must check your driver documentation to be sure that it implements
the particular features you want to use.
Package Specification
Related Documentation
The Java Series book published by Addison-Wesley Longman provides detailed
information about the classes and interfaces in the javax.sql
package:
@since 1.4
| javax.sql.rowset |
javax.sql.rowset Package
Standard interfaces and base classes for JDBC RowSet
implementations. This package contains interfaces and classes
that a standard RowSet implementation either implements or extends.
Table of Contents
This package specifies five standard JDBC RowSet interfaces.
All five extend the
RowSet interface described in the JDBC 3.0
specification. It is anticipated that additional definitions
of more specialized JDBC RowSet types will emerge as this technology
matures. Future definitions should be specified as subinterfaces using
inheritance similar to the way it is used in this specification.
Note: The interface definitions provided in this package form the basis for
all compliant JDBC RowSet implementations. Vendors and more advanced
developers who intend to provide their own compliant RowSet implementations
should pay particular attention to the assertions detailed in specification
interfaces.
JdbcRowSet - A wrapper around
a ResultSet object that makes it possible to use the result set as a
JavaBeansTM component. Thus,
a JdbcRowSet object can be a Bean that any tool
makes available for assembling an application as part of a component based
architecture . A JdbcRowSet object is a connected RowSet
object, that is, it
must continually maintain its connection to its data source using a JDBC
technology-enabled driver ("JDBC driver"). In addition, a JdbcRowSet
object provides a fully updatable and scrollable tabular
data structure as defined in the JDBC 3.0 specification.
-
CachedRowSet TM>
- A CachedRowSet object is a JavaBeansTM
component that is scrollable, updatable, serializable, and generally disconnected from
the source of its data. A CachedRowSet object
typically contains rows from a result set, but it can also contain rows from any
file with a tabular format, such as a spreadsheet. CachedRowSet implementations
must use the SyncFactory to manage and obtain pluggable
SyncProvider objects to provide synchronization between the
disconnected RowSet object and the originating data source.
Typically a SyncProvider implementation relies upon a JDBC
driver to obtain connectivity to a particular data source.
Further details on this mechanism are discussed in the javax.sql.rowset.spi package
specification.
WebRowSet - A
WebRowSet object is an extension of CachedRowSet
that can read and write a RowSet object in a well formed XML format.
This class calls an XmlReader object
(an extension of the RowSetReader
interface) to read a rowset in XML format. It calls an
XmlWriter object (an extension of the
RowSetWriter interface)
to write a rowset in XML format. The reader and writer required by
WebRowSet objects are provided by the
SyncFactory in the form of SyncProvider
implementations. In order to ensure well formed XML usage, a standard generic XML
Schema is defined and published at
http://java.sun.com/xml/ns/jdbc/webrowset.xsd .
FilteredRowSet - A
FilteredRowSet object provides filtering functionality in a programmatic
and extensible way. There are many instances when a RowSet object
has a need to provide filtering in its contents without sacrificing the disconnected
environment, thus saving the expense of having to create a connection to the data source.
Solutions to this need vary from providing heavyweight full scale
SQL query abilities, to portable components, to more lightweight
approaches. A FilteredRowSet object consumes
an implementation of the Predicate
interface, which may define a filter at run time. In turn, a
FilteredRowSet object is tasked with enforcing the set filter for both
inbound and outbound read and write operations. That is, all filters can be
considered as bi-directional. No standard filters are defined;
however, sufficient mechanics are specified to permit any required filter to be
implemented.
JoinRowSet - The JoinRowSet
interface describes a mechanism by which relationships can be established between
two or more standard RowSet implementations. Any number of RowSet
objects can be added to a JoinRowSet object provided the RowSetobjects
can be related in a SQL JOIN like fashion. By definition, the SQL JOIN
statement is used to combine the data contained in two (or more) relational
database tables based upon a common attribute. By establishing and then enforcing
column matches, a JoinRowSet object establishes relationships between
RowSet instances without the need to touch the originating data source.
Compliant implementations of JDBC RowSet Implementations
must follow the assertions described in this specification. In accordance
with the terms of the Java Community Process, a
Test Compatibility Kit (TCK) can be licensed to ensure compatibility with the
specification. The following paragraphs outline a number of starting points for
implementers of the standard JDBC RowSet definitions. Implementers
should also consult the Implementer's Guide in the javax.sql.rowset.spi package for guidelines
on SyncProvider implementations.
- 3.1 Role of the
BaseRowSet Class
A compliant JDBC RowSet implementation must implement one or more
standard interfaces specified in this package and and may extend the
BaseRowSet abstract class. For example, a
CachedRowSet implementation must implement the CachedRowSet
interface and extend the BaseRowSet abstract class. The
BaseRowSet class provides the standard architecture on which all
RowSet implementations should be built, regardless of whether the
RowSet objects exist in a connected or disconnected environment.
The BaseRowSet abstract class provides any RowSet implementation
with its base functionality, including property manipulation and event notification
that is fully compliant with JavaBeans
component requirements. As an example, all implementations provided in the
reference implementations (contained in the com.sun.rowset package) use
the BaseRowSet class as a basis for their implementations.
The following table illustrates the features that the BaseRowSet
abstract class provides.
Feature
|
Details
|
Properties
|
Provides standard JavaBeans property manipulation
mechanisms to allow applications to get and set RowSet command and
property values. Refer to the documentation of the javax.sql.RowSet
interface (available in the JDBC 3.0 specification) for more details on
the standard RowSet properties.
|
Event notification
|
Provides standard JavaBeans event notifications
to registered event listeners. Refer to the documentation of javax.sql.RowSetEvent
interface (available in the JDBC 3.0 specification) for
more details on how to register and handle standard RowSet events generated
by compliant implementations.
|
Setters for a RowSet object's command
|
Provides a complete set of setter methods
for setting RowSet command parameters.
|
Streams
|
Provides fields for storing of stream instances
in addition to providing a set of constants for stream type designation.
|
- 3.2 Connected RowSet Requirements
The JdbcRowSet describes a RowSet object that must always
be connected to the originating data source. Implementations of the JdbcRowSet
should ensure that this connection is provided solely by a JDBC driver.
Furthermore, RowSet objects that are implementations of the
JdbcRowSet interface and are therefore operating in a connected environment
do not use the SyncFactory to obtain a RowSetReader object
or a RowSetWriter object. They can safely rely on the JDBC driver to
supply their needs by virtue of the presence of an underlying updatable and scrollable
ResultSet implementation.
-
3.3 Disconnected RowSet Requirements
A disconnected RowSet object, such as a CachedRowSet object,
should delegate
connection management to a SyncProvider object provided by the
SyncFactory . To ensure fully disconnected semantics, all
disconnected RowSet objects must ensure
that the original connection made to the data source to populate the RowSet
object is closed to permit the garbage collector to recover and release resources. The
SyncProvider object ensures that the critical JDBC properties are
maintained in order to re-establish a connection to the data source when a
synchronization is required. A disconnected RowSet object should
therefore ensure that no
extraneous references remain on the Connection object.
- 3.4 Role of RowSetMetaDataImpl
The RowsetMetaDataImpl class is a utility class that provides an implementation of the
RowSetMetaData interface, supplying standard setter
method implementations for metadata for both connected and disconnected
RowSet objects. All implementations are free to use this standard
implementation but are not required to do so.
- 3.5 RowSetWarning Class
The RowSetWarning class provides warnings that can be set
on RowSet implementations.
Similar to SQLWarning objects,
RowSetWarning objects are silently chained to the object whose method
caused the warning to be thrown. All RowSet implementations should
ensure that this chaining occurs if a warning is generated and also ensure that the
warnings are available via the getRowSetWarnings method defined in either
the JdbcRowSet interface or the CachedRowSet interface.
After a warning has been retrieved with one of the
getRowSetWarnings methods, the RowSetWarning method
getNextWarning can be called on it to retrieve any warnings that might
be chained on it. If a warning is returned, getNextWarning can be called
on it, and so on until there are no more warnings.
- 3.6 The Joinable Interface
The Joinable interface provides both connected and disconnected
RowSet objects with the capability to be added to a
JoinRowSet object in an SQL JOIN operation.
A RowSet object that has implemented the Joinable
interface can set a match column, retrieve a match column, or unset a match column.
A JoinRowSet object can then use the RowSet object's
match column as a basis for adding the RowSet object.
| javax.sql.rowset.serial |
javax.sql.rowset.serial
Provides utility classes to allow serializable mappings between SQL types
and data types in the Java programming language.
Standard JDBC RowSet implementations may use these utility
classes to
assist in the serialization of disconnected RowSet objects.
This is useful
when transmitting a disconnected RowSet object over the wire to
a different VM or across layers within an application.
1.0 SerialArray
A serializable mapping in the Java programming language of an SQL ARRAY
value.
The SerialArray class provides a constructor for creating a SerialArray
instance from an Array object, methods for getting the base type and
the SQL name for the base type, and methods for copying all or part of a
SerialArray object.
2.0 SerialBlob
A serializable mapping in the Java programming language of an SQL BLOB
value.
The SerialBlob class provides a constructor for creating an instance
from a Blob object. Note that the Blob object should have brought the SQL
BLOB value's data over to the client before a SerialBlob object
is constructed from it. The data of an SQL BLOB value can be materialized
on the client as an array of bytes (using the method Blob.getBytes)
or as a stream of uninterpreted bytes (using the method Blob.getBinaryStream).
SerialBlob methods make it possible to make a copy of a SerialBlob
object as an array of bytes or as a stream. They also make it possible
to locate a given pattern of bytes or a Blob object within a SerialBlob
object.
3.0 SerialClob
A serializable mapping in the Java programming language of an SQL CLOB
value.
The SerialClob class provides a constructor for creating an instance
from a Clob object. Note that the Clob object should have
brought the SQL CLOB value's data over to the client before a SerialClob
object is constructed from it. The data of an SQL CLOB value can be
materialized on the client as a stream of Unicode characters.
SerialClob methods make it possible to get a substring from a
SerialClob object or to locate the start of a pattern of characters.
5.0 SerialDatalink
A serializable mapping in the Java programming language of an SQL DATALINK
value. A DATALINK value references a file outside of the underlying data source
that the the originating data source manages.
RowSet implementations can use the method RowSet.getURL() to retrieve
a java.net.URL object, which can be used to manipulate the external data.
java.net.URL url = rowset.getURL(1);
6.0 SerialJavaObject
A serializable mapping in the Java programming language of an SQL JAVA_OBJECT
value. Assuming the Java object instance implements the Serializable interface,
this simply wraps the serialization process.
If however, the serialization is not possible in the case where the Java
object is not immediately serializable, this class will attempt to serialize
all non static members to permit the object instance state to be serialized.
Static or transient fields cannot be serialized and attempting to do so
will result in a SerialException being thrown.
7.0 SerialRef
A serializable mapping between the SQL REF type and the Java programming
language.
The SerialRef class provides a constructor for creating a SerialRef
instance from a Ref type and provides methods for getting
and setting the Ref object type.
8.0 SerialStruct
A serializable mapping in the Java programming language of an SQL structured
type. Each attribute that is not already serializable is mapped to a serializable
form, and if an attribute is itself a structured type, each of its attributes
that is not already serializable is mapped to a serializable form.
In addition, if a Map object is passed to one of the constructors or
to the method getAttributes , the structured type is custom mapped
according to the mapping specified in the Map object.
The SerialStruct class provides a constructor for creating an
instance from a Struct object, a method for retrieving the SQL
type name of the SQL structured type in the database, and methods for retrieving
its attribute values.
9.0 SQLInputImpl
An input stream used for custom mapping user-defined types (UDTs). An
SQLInputImpl object is an input stream that contains a stream of
values that are
the attributes of a UDT. This class is used by the driver behind the scenes
when the method getObject is called on an SQL structured or distinct
type that has a custom mapping; a programmer never invokes SQLInputImpl
methods directly.
The SQLInputImpl class provides a set of reader methods
analogous to the ResultSet getter methods. These methods make it
possible to read the values in an SQLInputImpl object. The method
wasNull is used to determine whether the the last value read was SQL NULL.
When a constructor or getter method that takes a Map object is called,
the JDBC driver calls the method
SQLData.getSQLType to determine the SQL type of the UDT being custom
mapped. The driver creates an instance of SQLInputImpl , populating it with
the attributes of the UDT. The driver then passes the input stream to the
method SQLData.readSQL, which in turn calls the SQLInputImpl
methods to read the attributes from the input stream.
10.0 SQLOutputImpl
The output stream for writing the attributes of a custom mapped user-defined
type (UDT) back to the database. The driver uses this interface internally,
and its methods are never directly invoked by an application programmer.
When an application calls the method PreparedStatement.setObject, the
driver checks to see whether the value to be written is a UDT with a custom
mapping. If it is, there will be an entry in a type map containing the Class
object for the class that implements SQLData for this UDT. If the
value to be written is an instance of SQLData, the driver will
create an instance of SQLOutputImpl and pass it to the method
SQLData.writeSQL.
The method writeSQL in turn calls the appropriate SQLOutputImpl
writer methods to write data from the SQLData object to the
SQLOutputImpl
output stream as the representation of an SQL user-defined type.
Custom Mapping
The JDBC API provides mechanisms for mapping an SQL structured type or DISTINCT
type to the Java programming language. Typically, a structured type is mapped
to a class, and its attributes are mapped to fields in the class.
(A DISTINCT type can thought of as having one attribute.) However, there are
many other possibilities, and there may be any number of different mappings.
A programmer defines the mapping by implementing the interface SQLData .
For example, if an SQL structured type named AUTHORS has the attributes NAME,
TITLE, and PUBLISHER, it could be mapped to a Java class named Authors. The
Authors class could have the fields name, title, and publisher, to which the
attributes of AUTHORS are mapped. In such a case, the implementation of
SQLData could look like the following:
public class Authors implements SQLData {
public String name;
public String title;
public String publisher;
private String sql_type;
public String getSQLTypeName() {
return sql_type;
}
public void readSQL(SQLInput stream, String type)
throws SQLException {
sql_type = type;
name = stream.readString();
title = stream.readString();
publisher = stream.readString();
}
public void writeSQL(SQLOutput stream) throws SQLException {
stream.writeString(name);
stream.writeString(title);
stream.writeString(publisher);
}
}
A java.util.Map object is used to associate the SQL structured
type with its mapping to the class Authors . The following code fragment shows
how a Map object might be created and given an entry associating
AUTHORS and Authors .
java.util.Map map = new java.util.HashMap();
map.put("SCHEMA_NAME.AUTHORS", Class.forName("Authors");
The Map object map now contains an entry with the
fully qualified name of the SQL structured type and the Class
object for the class Authors . It can be passed to a method
to tell the driver how to map AUTHORS to Authors .
For a disconnected RowSet object, custom mapping can be done
only when a Map object is passed to the method or constructor
that will be doing the custom mapping. The situation is different for
connected RowSet objects because they maintain a connection
with the data source. A method that does custom mapping and is called by
a disconnected RowSet object may use the Map
object that is associated with the Connection object being
used. So, in other words, if no map is specified, the connection's type
map can be used by default.
| javax.sql.rowset.spi |
javax.sql.rowset.spi
The standard classes and interfaces that a third party vendor has to
use in its implementation of a synchronization provider. These classes and
interfaces are referred to as the Service Provider Interface (SPI). A vendor may
have its implementation included on the JDBC web page that lists available
SyncProvider implementations by sending email to jdbc@sun.com .
Doing this helps make developers aware of the implementation. To make it possible
for a RowSet object to use an implementation, the vendor must register
it with the SyncFactory singleton. (See the class comment for
SyncProvider for a full explanation of the registration process and
the naming convention to be used.)
Table of Contents
The following classes and interfaces make up the javax.sql.rowset.spi
package:
SyncFactory
SyncProvider
SyncFactoryException
SyncProviderException
SyncResolver
XmlReader
XmlWriter
TransactionalWriter
The following interfaces, in the javax.sql package, are also part of the SPI:
RowSetReader
RowSetWriter
A SyncProvider implementation provides a disconnected RowSet
object with the mechanisms for reading data into it and for writing data that has been
modified in it
back to the underlying data source. A reader, a RowSetReader or
XMLReader object, reads data into a RowSet object when the
CachedRowSet methods execute or populate
are called. A writer, a RowSetWriter or XMLWriter
object, writes changes back to the underlying data source when the
CachedRowSet method acceptChanges is called.
The process of writing changes in a RowSet object to its data source
is known as synchronization. The SyncProvider implementation that a
RowSet object is using determines the level of synchronization that the
RowSet object's writer uses. The various levels of synchronization are
referred to as grades.
The lower grades of synchronization are
known as optimistic concurrency levels because they optimistically
assume that there will be no conflicts or very few conflicts. A conflict exists when
the same data modified in the RowSet object has also been modified
in the data source. Using the optimistic concurrency model means that if there
is a conflict, modifications to either the data source or the RowSet
object will be lost.
Higher grades of synchronization are called pessimistic because they assume
that others will be accessing the data source and making modifications. These
grades set varying levels of locks to increase the chances that no conflicts
occur.
The lowest level of synchronization is simply writing any changes made to the
RowSet object to its underlying data source. The writer does
nothing to check for conflicts.
If there is a conflict and the data
source values are overwritten, the changes other parties have made by to the data
source are lost.
The RIXMLProvider implementation uses the lowest level
of synchronization and just writes RowSet changes to the data source.
This is true because typically XML data sources do not enable transaction
techniques for maintaining the integrity of data. However, specific standards
groups have considered offering XML-based synchronization. For details, see
http://www.syncml.org
For the the next level up, the
writer checks to see if there are any conflicts, and if there are,
it does not write anything to the data source. The problem with this concurrency
level is that if another party has modified the corresponding data in the data source
since the RowSet object got its data,
the changes made to the RowSet object are lost. The
RIOptimisticProvider implementation uses this level of synchronization.
At higher levels of synchronization, referred to as pessimistic concurrency,
the writer take steps to avoid conflicts by setting locks. Setting locks
can vary from setting a lock on a single row to setting a lock on a table
or the entire data source. The level of synchronization is therefore a tradeoff
between the ability of users to access the data source concurrently and the ability
of the writer to keep the data in the RowSet object and its data source
synchronized.
It is a requirement that all disconnected RowSet objects
(CachedRowSet , FilteredRowSet , JoinRowSet ,
and WebRowSet objects) obtain their SyncProvider objects
from the SyncFactory mechanism.
The reference implementation (RI) provides two synchronization providers.
- RIOptimisticProvider
The default provider that the SyncFactory instance will
supply to a disconnected RowSet object when no provider
implementation is specified.
This synchronization provider uses an optimistic concurrency model,
assuming that there will be few conflicts among users
who are accessing the same data in a database. It avoids
using locks; rather, it checks to see if there is a conflict
before trying to synchronize the RowSet object and the
data source. If there is a conflict, it does nothing, meaning that
changes to the RowSet object are not persisted to the data
source.
- RIXMLProvider
A synchronization provider that can be used with a
WebRowSet object, which is a rowset that can be written
in XML format or read from XML format. The
RIXMLProvider implementation does no checking at all for
conflicts and simply writes any updated data in the
WebRowSet object to the underlying data source.
WebRowSet objects use this provider when they are
dealing with XML data.
These SyncProvider implementations
are bundled with the reference implementation, which makes them always available to
RowSet implementations.
SyncProvider implementations make themselves available by being
registered with the SyncFactory singleton. When a RowSet
object requests a provider, by specifying it in the constructor or as an argument to the
CachedRowSet method setSyncProvider ,
the SyncFactory singleton
checks to see if the requested provider has been registered with it.
If it has, the SyncFactory creates an instance of it and passes it to the
requesting RowSet object.
If the SyncProvider implementation that is specified has not been registered,
the SyncFactory singleton causes a SyncFactoryException object
to be thrown. If no provider is specified,
the SyncFactory singleton will create an instance of the default
provider implementation, RIOptimisticProvider ,
and pass it to the requesting RowSet object.
If a WebRowSet object does not specify a provider in its constructor, the
SyncFactory will give it an instance of RIOptimisticProvider .
However, the constructor for WebRowSet is implemented to set the provider
to the RIXMLProvider , which reads and writes a RowSet object
in XML format.
See the SyncProvider class
specification for further details.
Vendors may develop a SyncProvider implementation with any one of the possible
levels of synchronization, thus giving RowSet objects a choice of
synchronization mechanisms. A vendor can make its implementation available by
registering the fully qualified class name with Sun Microsystems at
jdbc@sun.com . This process is discussed in further detail below.
2.0 Service Provider Interface Architecture
2.1 Overview
The Service Provider Interface provides a pluggable mechanism by which
SyncProvider implementations can be registered and then generated when
required. The lazy reference mechanism employed by the SyncFactory limits
unnecessary resource consumption by not creating an instance until it is
required by a disconnected
RowSet object. The SyncFactory class also provides
a standard API to configure logging options and streams that may be provided
by a particular SyncProvider implementation.
2.2 Registering with the SyncFactory
A third party SyncProvider implementation must be registered with the
SyncFactory in order for a disconnected RowSet object
to obtain it and thereby use its javax.sql.RowSetReader and
javax.sql.RowSetWriter
implementations. The following registration mechanisms are available to all
SyncProvider implementations:
- System properties - Properties set at the command line. These
properties are set at run time and apply system-wide per invocation of the Java
application. See the section "Related Documentation"
further related information.
- Property Files - Properties specified in a standard property file.
This can be specified using a System Property or by modifying a standard
property file located in the platform run-time. The
reference implementation of this technology includes a standard property
file than can be edited to add additional
SyncProvider objects.
- JNDI Context - Available providers can be registered on a JNDI
context. The SyncFactory will attempt to load SyncProvider
objects bound to the context and register them with the factory. This
context must be supplied to the
SyncFactory for the mechanism to
function correctly.
Details on how to specify the system properties or properties in a property file
and how to configure the JNDI Context are explained in detail in the
SyncFactory class description.
2.3 SyncFactory Provider Instance Generation Policies
The SyncFactory generates a requested SyncProvider
object if the provider has been correctly registered. The
following policies are adhered to when either a disconnected RowSet object
is instantiated with a specified SyncProvider implementation or is
reconfigured at runtime with an alternative SyncProvider object.
- If a
SyncProvider object is specified and the SyncFactory
contains no reference to the provider, a SyncFactoryException is
thrown.
- If a
SyncProvider object is specified and the SyncFactory
contains a reference to the provider, the requested provider is supplied.
- If no
SyncProvider object is specified, the reference
implementation provider RIOptimisticProvider is supplied.
These policies are explored in more detail in the
SyncFactory class.
3.0 SyncProvider Implementer's Guide
3.1 Requirements
A compliant SyncProvider implementation that is fully pluggable
into the SyncFactory must extend and implement all
abstract methods in the SyncProvider
class. In addition, an implementation must determine the
grade, locking and updatable view capabilities defined in the
SyncProvider class definition. One or more of the
SyncProvider description criteria must be supported. It
is expected that vendor implementations will offer a range of grade, locking, and
updatable view capabilities.
Furthermore, the SyncProvider naming convention must be followed as
detailed in the SyncProvider class
description.
3.2 Grades
JSR 114 defines a set of grades to describe the quality of synchronization
a SyncProvider object can offer a disconnected RowSet
object. These grades are listed from the lowest quality of service to the highest.
- GRADE_NONE - No synchronization with the originating data source is
provided. A
SyncProvider implementation returning this grade will simply
attempt to write any data that has changed in the RowSet object to the
underlying data source, overwriting whatever is there. No attempt is made to compare
original values with current values to see if there is a conflict. The
RIXMLProvider is implemented with this grade.
- GRADE_CHECK_MODIFIED_AT_COMMIT - A low grade of optimistic synchronization.
A
SyncProvider implementation returning this grade
will check for conflicts in rows that have changed between the last synchronization
and the current synchronization under way. Any changes in the originating data source
that have been modified will not be reflected in the disconnected RowSet
object. If there are no conflicts, changes in the RowSet object will be
written to the data source. If there are conflicts, no changes are written.
The RIOptimisticProvider implementation uses this grade.
- GRADE_CHECK_ALL_AT_COMMIT - A high grade of optimistic synchronization.
A
SyncProvider implementation returning this grade
will check all rows, including rows that have not changed in the disconnected
RowSet object. In this way, any changes to rows in the underlying
data source will be reflected in the disconnected RowSet object
when the synchronization finishes successfully.
- GRADE_LOCK_WHEN_MODIFIED - A pessimistic grade of synchronization.
SyncProvider implementations returning this grade will lock
the row in the originating data source that corresponds to the row being changed
in the RowSet object to reduce the possibility of other
processes modifying the same data in the data source.
- GRADE_LOCK_WHEN_LOADED - A higher pessimistic synchronization grade.
A
SyncProvider implementation returning this grade will lock
the entire view and/or table affected by the original query used to
populate a RowSet object.
3.3 Locks
JSR 114 defines a set of constants that specify whether any locks have been
placed on a RowSet object's underlying data source and, if so,
on which constructs the locks are placed. These locks will remain on the data
source while the RowSet object is disconnected from the data source.
These constants should be considered complementary to the
grade constants. The default setting for the majority of grade settings requires
that no data source locks remain when a RowSet object is disconnected
from its data source.
The grades GRADE_LOCK_WHEN_MODIFIED and
GRADE_LOCK_WHEN_LOADED allow a disconnected RowSet object
to have a fine-grained control over the degree of locking.
- DATASOURCE_NO_LOCK - No locks remain on the originating data source.
This is the default lock setting for all
SyncProvider implementations
unless otherwise directed by a RowSet object.
- DATASOURCE_ROW_LOCK - A lock is placed on the rows that are touched by
the original SQL query used to populate the
RowSet object.
- DATASOURCE_TABLE_LOCK - A lock is placed on all tables that are touched
by the query that was used to populate the
RowSet object.
- DATASOURCE_DB_LOCK
A lock is placed on the entire data source that is used by the
RowSet
object.
3.4 Updatable Views
A RowSet object may be populated with data from an SQL VIEW .
The following constants indicate whether a SyncProvider object can
update data in the table or tables from which the VIEW was derived.
- UPDATABLE_VIEW_SYNC
Indicates that a
SyncProvider implementation supports synchronization
to the table or tables from which the SQL VIEW used to populate a
a RowSet object is derived.
- NONUPDATABLE_VIEW_SYNC
Indicates that a
SyncProvider implementation does not support
synchronization to the table or tables from which the SQL VIEW
used to populate a RowSet object is derived.
3.5 Usage of SyncProvider Grading and Locking
In the example below, the reference CachedRowSetImpl implementation
reconfigures its current SyncProvider object by calling the
setSyncProvider method.
CachedRowSetImpl crs = new CachedRowSetImpl();
crs.setSyncProvider("com.foo.bar.HASyncProvider");
An application can retrieve the SyncProvider object currently in use
by a disconnected RowSet object. It can also retrieve the
grade of synchronization with which the provider was implemented and the degree of
locking currently in use. In addition, an application has the flexibility to set
the degree of locking to be used, which can increase the possibilities for successful
synchronization. These operation are shown in the following code fragment.
SyncProvider sync = crs.getSyncProvider();
switch (sync.getProviderGrade()) {
case: SyncProvider.GRADE_CHECK_ALL_AT_COMMIT
//A high grade of optimistic synchronization
break;
case: SyncProvider.GRADE_CHECK_MODIFIED_AT_COMMIT
//A low grade of optimistic synchronization
break;
case: SyncProvider.GRADE_LOCK_WHEN_LOADED
// A pessimistic synchronization grade
break;
case: SyncProvider.GRADE_LOCK_WHEN_MODIFIED
// A pessimistic synchronization grade
break;
case: SyncProvider.GRADE_NONE
// No synchronization with the originating data source provided
break;
}
switch (sync.getDataSourcLock() {
case: SyncProvider.DATASOURCE_DB_LOCK
// A lock is placed on the entire datasource that is used by the
// RowSet object
break;
case: SyncProvider.DATASOURCE_NO_LOCK
// No locks remain on the originating data source.
break;
case: SyncProvider.DATASOURCE_ROW_LOCK
// A lock is placed on the rows that are touched by the original
// SQL statement used to populate
// the RowSet object that is using the SyncProvider
break;
case: DATASOURCE_TABLE_LOCK
// A lock is placed on all tables that are touched by the original
// SQL statement used to populated
// the RowSet object that is using the SyncProvider
break;
It is also possible using the static utility method in the
SyncFactory class to determine the list of SyncProvider
implementations currently registered with the SyncFactory .
Enumeration e = SyncFactory.getRegisteredProviders();
The interface SyncResolver provides a way for an application to
decide manually what to do when a conflict occurs. When the CachedRowSet
method acceptChanges finishes and has detected one or more conflicts,
it throws a SyncProviderException object. An application can
catch the exception and
have it retrieve a SyncResolver object by calling the method
SyncProviderException.getSyncResolver() .
A SyncResolver object, which is a special kind of
CachedRowSet object or
a JdbcRowSet object that has implemented the SyncResolver
interface, examines the conflicts row by row. It is a duplicate of the
RowSet object being synchronized except that it contains only the data
from the data source this is causing a conflict. All of the other column values are
set to null . To navigate from one conflict value to another, a
SyncResolver object provides the methods nextConflict and
previousConflict .
The SyncResolver interface also
provides methods for doing the following:
- finding out whether the conflict involved an update, a delete, or an insert
- getting the value in the data source that caused the conflict
- setting the value that should be in the data source if it needs to be changed
or setting the value that should be in the
RowSet object if it needs
to be changed
When the CachedRowSet method acceptChanges is called, it
delegates to the RowSet object's SyncProvider object.
How the writer provided by that SyncProvider object is implemented
determines what level (grade) of checking for conflicts will be done. After all
checking for conflicts is completed and one or more conflicts has been found, the method
acceptChanges throws a SyncProviderException object. The
application can catch the exception and use it to obtain a SyncResolver object.
The application can then use SyncResolver methods to get information
about each conflict and decide what to do. If the application logic or the user
decides that a value in the RowSet object should be the one to
persist, the application or user can overwrite the data source value with it.
The comment for the SyncResolver interface has more detail.
5.0 Related Specifications
6.0 Related Documentation
|
|