Oracle® Database JDBC Developer's Guide and Reference 10g Release 2 (10.2) Part Number B14355-01 |
|
|
View PDF |
This chapter covers the following topics:
The server-side internal driver is intrinsically tied to the Oracle Database and to the Java virtual machine (JVM). The driver runs as part of the same process as the database. It also runs within the default session, the same session in which the JVM was started.
The server-side internal driver is optimized to run within the database server and provide direct access to SQL data and PL/SQL subprograms on the local database. The entire JVM operates in the same address space as the database and the SQL engine. Access to the SQL engine is a function call. This enhances the performance of your Java Database Connectivity (JDBC) applications and is much faster than running a remote Oracle Net call to access the SQL engine.
The server-side internal driver supports the same features, application programming interfaces (APIs), and Oracle extensions as the client-side drivers. This makes application partitioning very straightforward. For example, if you have a Java application that is data-intensive, then you can easily move it into the database server for better performance, without having to modify the application-specific calls.
As described in the preceding section, the server-side internal driver runs within a default session. Therefore, you are already connected. There are two methods to access the default connection:
Use the OracleDataSource.getConnection
method, with either jdbc:oracle:kprb
or jdbc:default:connection
as the URL string.
Use the Oracle-specific defaultConnection
method of the OracleDriver
class.
Using defaultConnection
is generally recommended.
Note: You are no longer required to register theOracleDriver class for connecting with the server-side internal driver. |
Connecting with the OracleDriver Class defaultConnection Method
The defaultConnection
method of the oracle.jdbc.OracleDriver
class is an Oracle extension and always returns the same connection object. Even if you call this method multiple times, assigning the resulting connection object to different variable names, then only a single connection object is reused.
You need not include a connect string in the defaultConnection
call. For example:
import java.sql.*; import oracle.jdbc.*; class JDBCConnection { public static Connection connect() throws SQLException { Connection conn = null; try { // connect with the server-side internal driver OracleDriver ora = new OracleDriver(); conn = ora.defaultConnection(); } } catch (SQLException e) {...} return conn; } }
Note that there is no conn.close
call in the example. When JDBC code is running inside the target server, the connection is an implicit data channel, not an explicit connection instance as from a client. It should not be closed.
If you do call the close
method, then be aware of the following:
All connection instances obtained through the defaultConnection
method, which actually reference the same database connection, will be closed and unavailable for further use, with state and resource cleanup as appropriate. Running defaultConnection
afterward would result in a new connection object.
Even though the connection object is closed, the implicit connection to the database will not be closed.
Connecting with the OracleDataSource.getConnection Method
To connect to the internal server connection from code that is running within the target server, you can use the OracleDataSource.getConnection
method with either of the following URLs:
OracleDataSource ods = new OracleDataSource(); ods.setURL("jdbc:oracle:kprb:"); Connection conn = ods.getConnection();
or:
OracleDataSource ods = new OracleDataSource(); ods.setURL("jdbc:default:connection:"); Connection conn = ods.getConnection();
Any user name or password you include in the URL is ignored in connecting to the default server connection.
The OracleDataSource.getConnection
method returns a new Java Connection
object every time you call it. Note that although the method is not creating a new database connection, it is returning a new object.
The fact that OracleDataSource.getConnection
returns a new connection object every time you call it is significant if you are working with object maps or type maps. A type map is associated with a specific Connection
object and with any state that is part of the object. If you want to use multiple type maps as part of your program, then you can call getConnection
to create a new Connection
object for each type map.
The server-side internal driver, in addition to having standard exception-handling capabilities, such as getMessage()
, getErrorCode()
, and getSQLState()
, offers extended features through the oracle.jdbc.driver.OracleSQLException
class. This class is a subclass of the standard java.sql.SQLException
class and is not available to the client-side JDBC drivers or the server-side Thin driver.
When an error condition occurs in the server, it often results in a series of related errors being placed in an internal error stack. The JDBC server-side internal driver retrieves errors from the stack and places them in a chain of OracleSQLException
objects.
You can use the following methods in processing these exceptions:
SQLException getNextException()
This method returns the next exception in the chain or null
if there are no further exceptions. You can start with the first exception you receive and work through the chain. This is a standard method.
int getNumParameters()
(Oracle extension)
Errors from the server usually include parameters, or variables, that are part of the error message. These may indicate what type of error occurred, what kind of operation was being attempted, or the invalid or affected values. This method returns the number of parameters included with this error. It is an Oracle extension.
Object[] getParameters()
(Oracle extension)
This method returns a Java Object[]
array containing the parameters included with this error. It is an Oracle extension.
Example
Following is an example of server-side error processing:
try { // should get "ORA-942: table or view does not exist" stmt.execute("drop table no_such_table"); } catch (OracleSQLException e) { System.out.println(e.getMessage()); // prints "ORA-942: table or view does not exist" System.out.println(e.getNumParameters()); // prints "1" Object[] params = e.getParameters(); System.out.println(params[0]); // prints "NO_SUCH_TABLE" }
The server-side driver operates within a default session and default transaction context. The default session is the session in which the JVM was started. In effect, you are already connected to the database on the server. This is different from the client side where there is no default session. You must explicitly connect to the database.
Auto-commit mode is disabled in the server. You must manage transaction COMMIT
and ROLLBACK
operations explicitly by using the appropriate methods on the connection object:
conn.commit();
or:
conn.rollback();
Note: As a best practice, it is recommended not to commit or rollback a transaction inside the server. |
Almost any JDBC program that can run on a client can also run on the server. All the programs in the samples
directory can be run on the server, with only minor modifications. Usually, these modifications concern only the connection statement.
Consider the following code fragment which obtains a connection to a database:
ods.setUrl( "jdbc:oracle:oci:@(DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=cluster_alias) (PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=service_name)))"); ods.setUser("scott"); ods.setPassword("tiger"); Connection conn = ods.getConnection();
We can modify this code fragment for use in the server-side internal driver. In the server-side internal driver, no user, password, or database information is necessary. For the connection statement, you use:
ods.setUrl( "jdbc:oracle:kprb:@"); Connection conn = ods.getConnection();
However, the most convenient way to get a connection is to call the OracleDriver.defaultConnection
method, as follows:
Connection conn = OracleDriver.defaultConnection();
When loading an application into the server, you can load .class
files that you have already compiled on the client or you can load .java
source files and have them automatically compiled on the server.
In either case, use the loadjava
utility to load your files. You can either specify source file names on the command line or put the files into a Java Archive (JAR) file and specify the JAR file name on the command line.
The loadjava
script, which runs the actual utility, is in the bin
directory in your Oracle home. This directory should already be in your path once Oracle has been installed.
Note: Theloadjava utility supports compressed files. |
Loading Class Files into the Server
Consider a case where you have the following three class files in your application: Foo1.class
, Foo2.class
, and Foo3.class
. Each class is written into its own class schema object in the server.
You can load the class files using the default JDBC Oracle Call Interface (OCI) driver in the following ways:
Specifying the individual class file names, as follows:
loadjava -user scott/tiger Foo1.class Foo2.class Foo3.class
Specifying the class file names using a wildcard, as follows:
loadjava -user scott/tiger Foo*.class
Specifying a JAR file that contains the class files, as follows:
loadjava -user scott/tiger Foo.jar
You can load the files using the JDBC Thin driver, as follows:
loadjava -thin -user scott/tiger@localhost:1521:ORCL Foo.jar
Note: Because the server-side embedded JVM uses Java Development Kit (JDK) 1.4, it is advisable to compile classes under JDK 1.4, if they will be loaded into the server. This will catch incompatibilities during compilation, instead of at run time. |
Loading Source Files into the Server
If you enable the loadjava -resolve
option when loading a .java
source file, then the server-side compiler will compile your application as it is loaded, resulting in both a source schema object for the original source code and one or more class schema objects for the compiled output.
If you do not specify -resolve
, then the source is loaded into a source schema object without any compilation. In this case, however, the source is implicitly compiled the first time an attempt is made to use a class defined in the source.
For example, run loadjava
as follows to load and compile Foo.java
, using the default JDBC OCI driver:
loadjava -user scott/tiger -resolve Foo.java
Or, use the following command to load using the JDBC Thin driver:
loadjava -thin -user scott/tiger@localhost:1521:ORCL -resolve Foo.java
Either of these will result in appropriate class schema objects being created in addition to the source schema object.
Note: Oracle generally recommends compiling source on the client, whenever possible, and loading the.class files instead of the source files into the server. |
The server-side internal driver performs character set conversions for oracle.sql.CHAR
in C. This is a different implementation than that for the client-side drivers, which perform character set conversions for oracle.sql.CHAR
in Java, and offers better performance. However, java.lang.String
offers better performance than oracle.sql.CHAR
even in the server-side internal driver.