This chapter discusses connecting applications to databases using Java Database Connectivity (JDBC) data sources, as well as the URLs that describe databases. This chapter contains the following sections:
Data sources are standard, general-use objects for specifying databases or other resources to use. The JDBC 2.0 extension application programming interface (API) introduced the concept of data sources. For convenience and portability, data sources can be bound to Java Naming and Directory Interface (JNDI) entities, so that you can access databases by logical names.
The data source facility provides a complete replacement for the previous JDBCDriverManager facility. You can use both facilities in the same application, but it is recommended that you transition your application to data sources.
This section covers the following topics:
The JNDI standard provides a way for applications to find and access remote services and resources. These services can be any enterprise services. However, for a JDBC application, these services would include database connections and services.
JNDI allows an application to use logical names in accessing these services, removing vendor-specific syntax from application code. JNDI has the functionality to associate a logical name with a particular source for a desired service.
All Oracle JDBC data sources are JNDI-referenceable. The developer is not required to use this functionality, but accessing databases through JNDI logical names makes the code more portable.
Note:
Using JNDI functionality requires thejndi.jar file to be in theCLASSPATH environment variable. This file is included with the Java products on the installation CD. You must add it to theCLASSPATH environment variable separately. You can also obtain it from the Sun Microsystems Web site, but it is advisable to use the version from Oracle, because it has been tested with the Oracle drivers.By using the data source functionality with JNDI, you do not need to register the vendor-specific JDBC driver class name and you can use logical names for URLs and other properties. This ensures that the code for opening database connections is portable to other environments.
The DataSource Interface and Oracle Implementation
A JDBC data source is an instance of a class that implements the standardjavax.sql.DataSource interface:
public interface DataSource{ Connection getConnection() throws SQLException; Connection getConnection(String username, String password) throws SQLException; ...}Oracle implements this interface with theOracleDataSource class in theoracle.jdbc.pool package. The overloadedgetConnection method returns a connection to the database.
To use other values, you can set properties using appropriate setter methods. For alternative user names and passwords, you can also use thegetConnection method that takes these parameters as input. This would take priority over the property settings.
Note:
TheOracleDataSource class and all subclasses implement thejava.io.Serializable andjavax.naming.Referenceable interfaces.TheOracleDataSource class, as with any class that implements theDataSource interface, provides a set of properties that can be used to specify a database to connect to. These properties follow the JavaBeans design pattern.
Table 8-1 andTable 8-2 listOracleDataSource properties. The properties inTable 8-1 are standard properties according to the Sun Microsystems specification. The properties inTable 8-2 are Oracle extensions.
Note:
Oracle does not implement the standardroleName property.Table 8-1 Standard Data Source Properties
| Name | Type | Description |
|---|---|---|
|
| Name of the particular database on the server. Also known as the SID in Oracle terminology. |
|
| Name of the underlying data source class. For connection pooling, this is an underlying pooled connection data source class. For distributed transactions, this is an underlying XA data source class. |
|
| Description of the data source. |
|
| Network protocol for communicating with the server. For Oracle, this applies only to the JDBC Oracle Call Interface (OCI) drivers and defaults to |
|
| Password for the connecting user. |
|
| Number of the port where the server listens for requests |
|
| Name of the database server |
|
| Name for the login |
TheOracleDataSource class implements the following setter and getter methods for the standard properties:
public synchronized void setDatabaseName(String dbname)
public synchronized String getDatabaseName()
public synchronized void setDataSourceName(String dsname)
public synchronized String getDataSourceName()
public synchronized void setDescription(String desc)
public synchronized String getDescription()
public synchronized void setNetworkProtocol(String np)
public synchronized String getNetworkProtocol()
public synchronized void setPassword(String pwd)
public synchronized void setPortNumber(int pn)
public synchronized int getPortNumber()
public synchronized void setServerName(String sn)
public synchronized String getServerName()
public synchronized void setUser(String user)
public synchronized String getUser()
Table 8-2 Oracle Extended Data Source Properties
| Name | Type | Description |
|---|---|---|
|
| Specifies the name of the cache. This cannot be changed after the cache has been created. |
|
| Specifies properties for implicit connection cache. |
|
| Specifies whether implicit connection cache is in use. |
|
| Specifies the connection properties. |
| Specifies Oracle JDBC driver type. It can be one of | |
|
| Specifies whether Fast Connection Failover is in use. |
|
| Specifies whether the implicit statement connection cache is enabled. |
|
| Specifies the maximum time in seconds that this data source will wait while attempting to connect to a database. |
|
| Specifies the log writer for this data source. |
|
| Specifies the maximum number of statements in the application cache. |
|
| Specifies the database service name for this data source. |
| Specifies the TNS entry name, relevant only for the OCI driver. The TNS entry name corresponds to the TNS entry specified in the Enable this | |
| Specifies the URL of the database connection string. Provided as a convenience, it can help you migrate from an older Oracle Database. You can use this property in place of the Oracle | |
| Allows an This | |
|
| Specifies the ONS configuration string that is used to remotely subscribe to FaN/ONS events. |
Note:
This table omits properties that supported the deprecated connection cache based onOracleConnectionCache.
Because Native XA performs better than Java XA, use Native XA whenever possible.
TheOracleDataSource class implements the followingsetXXX andgetXXX methods for the Oracle extended properties:
String getConnectionCacheName()
java.util.Properties getConnectionCacheProperties()
void setConnectionCacheProperties(java.util.Properties cp)
java.util.Properties getConnectionProperties()
void setConnectionProperties(java.util.Properties cp)
Note:
Use thesetConnectionProperties method to set the properties of the connection and thesetConnectionCacheProperties method to set the properties of the connection cache.For more information about the properties of the connection refer to"Supported Connection Properties".
For more information about the properties of the connection refer to"Connection Cache Properties".
boolean getConnectionCachingEnabled()
void setImplicitCachingEnabled()
String getDriverType()
void setDriverType(String dt)
String getURL()
void setURL(String url)
String getTNSEntryName()
void setTNSEntryName(String tns)
boolean getNativeXA()
void setNativeXA(boolean nativeXA)
String getONSConfiguration()
void setONSConfiguration(String onsConfig)
If you are using the server-side internal driver, that is, thedriverType property is set tokprb, then any other property settings are ignored.
If you are using the JDBC Thin or OCI driver, then note the following:
A URL setting can include settings foruser andpassword, as in the following example, in which case this takes precedence over individualuser andpassword property settings:
jdbc:oracle:thin:scott/tiger@localhost:1521:orcl
Settings foruser andpassword are required, either directly through the URL setting or through thegetConnection call. Theuser andpassword settings in agetConnection call take precedence over any property settings.
If theurl property is set, then anytnsEntry,driverType,portNumber,networkProtocol,serverName, anddatabaseName property settings are ignored.
If thetnsEntry property is set, which presumes theurl property is not set, then anydatabaseName,serverName,portNumber, andnetworkProtocol settings are ignored.
If you are using an OCI driver, which presumes thedriverType property is set tooci, and thenetworkProtocol is set toipc, then any other property settings are ignored.
Also, note thatgetConnectionCacheName() will return the name of the cache only if theConnectionCacheName property of the data source is set after caching is enabled on the data source.
This section shows an example of the most basic use of a data source to connect to a database, without using JNDI functionality. Note that this requires vendor-specific, hard-coded property settings.
Create anOracleDataSource instance, initialize its connection properties as appropriate, and get a connection instance, as in the following example:
OracleDataSource ods = new OracleDataSource();ods.setDriverType("oci");ods.setServerName("dlsun999");ods.setNetworkProtocol("tcp");ods.setDatabaseName("816");ods.setPortNumber(1521);ods.setUser("scott");ods.setPassword("tiger");Connection conn = ods.getConnection();Or, optionally, override the user name and password, as follows:
Connection conn = ods.getConnection("bill", "lion");This section exhibits JNDI functionality in using data sources to connect to a database. Vendor-specific, hard-coded property settings are required only in the portion of code that binds a data source instance to a JNDI logical name. From that point onward, you can create portable code by using the logical name in creating data sources from which you will get your connection instances.
Note:
Creating and registering data sources is typically handled by a JNDI administrator, not in a JDBC application.Initialize Data Source Properties
Create anOracleDataSource instance, and then initialize its properties as appropriate, as in the following example:
OracleDataSource ods = new OracleDataSource();ods.setDriverType("oci");ods.setServerName("dlsun999");ods.setNetworkProtocol("tcp");ods.setDatabaseName("816");ods.setPortNumber(1521);ods.setUser("scott");ods.setPassword("tiger");Once you have initialized the connection properties of theOracleDataSource instanceods, as shown in the preceding example, you can register this data source instance with JNDI, as in the following example:
Context ctx = new InitialContext();ctx.bind("jdbc/sampledb", ods);Calling the JNDIInitialContext() constructor creates a Java object that references the initial JNDI naming context. System properties, which are not shown, instruct JNDI which service provider to use.
Thectx.bind call binds theOracleDataSource instance to a logical JNDI name. This means that anytime after thectx.bind call, you can use the logical namejdbc/sampledb in opening a connection to the database described by the properties of theOracleDataSource instanceods. The logical namejdbc/sampledb is logically bound to this database.
The JNDI namespace has a hierarchy similar to that of a file system. In this example, the JNDI name specifies the subcontextjdbc under the root naming context and specifies the logical namesampledb within thejdbc subcontext.
TheContext interface andInitialContext class are in the standardjavax.naming package.
Note:
The JDBC 2.0 Specification requires that all JDBC data sources be registered in thejdbc naming subcontext of a JNDI namespace or in a child subcontext of thejdbc subcontext.To perform a lookup and open a connection to the database logically bound to the JNDI name, use the logical JNDI name. Doing this requires casting the lookup result, which is otherwise a JavaObject, toOracleDataSource and then using itsgetConnection method to open the connection.
OracleDataSource odsconn = (OracleDataSource)ctx.lookup("jdbc/sampledb");Connection conn = odsconn.getConnection();For a detailed list of connection properties that Oracle JDBC drivers support, see the Javadoc.
To specify the role for theSYS login, use theinternal_logon connection property. To logon asSYS, set theinternal_logon connection property toSYSDBA orSYSOPER.
Note:
The ability to specify a role is supported only for thesys user name.For a bequeath connection, we can get a connection asSYS by setting theinternal_logon property. For a remote connection, we need additional password file setting procedures.
Before the JDBC Thin driver can connect to the database asSYSDBA, you must configure the user, because Oracle Database security system requires a password file for remote connections as an administrator. Perform the following:
Set a password file on the server-side or on the remote database, using theorapwd password utility. You can add a password file for usersys as follows:
In UNIX
orapwd file=$ORACLE_HOME/dbs/orapw entries=200Enter password:passwordIn Microsoft Windows
orapwd file=%ORACLE_HOME%\database\PWDsid_name.ora entries=200Enter password:password
file must be the name of the password file.password is the password for the userSYS. It can be altered using theALTER USER statement in SQL Plus. You should setentries to a value higher than the number of entries you expect.
The syntax for the password file name is different on Microsoft Windows and UNIX.
Enable remote login assysdba. This step grantsSYSDBA andSYSOPER system privileges to individual users and lets them connect as themselves.
Stop the database, and add the following line toinitservice_name.ora, in UNIX, orinit.ora, in Microsoft Windows:
remote_login_passwordfile=exclusive
Theinitservice_name.ora file is located atORACLE_HOME/dbs/ and also atORACLE_HOME/admin/db_name/pfile/. Ensure that you keep the two files synchronized.
Theinit.ora file is located at%ORACLE_BASE%\ADMIN\db_name\pfile\.
Change the password for theSYS user. This is an optional step.
PASSWORD sys Changing password for sysNew password:passwordRetype new password:password
Verify whetherSYS has theSYSDBA privilege.
SQL> select * from v$pwfile_users;USERNAME SYSDB SYSOP---------------------- --------- ---------SYS TRUE TRUE
Restart the remote database.
Example 8-1 Using SYS Login To Make a Remote Connection
//This example works regardless of language settings of the database. /** case of remote connection using sys **/import java.sql.*;import oracle.jdbc.*;import oracle.jdbc.pool.*;// create an OracleDataSourceOracleDataSource ods = new OracleDataSource();// set connection propertiesjava.util.Properties prop = new java.util.Properties();prop.put("user", "sys");prop.put("password", "sys");prop.put("internal_logon", "sysoper");ods.setConnectionProperties(prop);// set the url// the url can use oci driver as well as:// url = "jdbc:oracle:oci8:@inst1"; the inst1 is a remote databaseString url = "jdbc:oracle:thin:@//myHost:1521/service_name";ods.setURL(url);// get the connectionConnection conn = ods.getConnection();...The following example illustrates how to use theinternal_logon andSYSDBA arguments to specify theSYS login. This example works regardless of the database's national-language settings of the database.
/** Example of bequeath connection **/import java.sql.*;import oracle.jdbc.*;import oracle.jdbc.pool.*; // create an OracleDataSource instanceOracleDataSource ods = new OracleDataSource(); // set neccessary propertiesjava.util.Properties prop = new java.util.Properties();prop.put("user", "sys");prop.put("password", "sys");prop.put("internal_logon", "sysdba");ods.setConnectionProperties(prop); // the url for bequeath connectionString url = "jdbc:oracle:oci8:@";ods.setURL(url); // retrieve the connectionConnection conn = ods.getConnection();...Some of the connection properties are for use with Oracle performance extensions. Setting these properties is equivalent to using corresponding methods on theOracleConnection object, as follows:
Setting thedefaultRowPrefetch property is equivalent to callingsetDefaultRowPrefetch.
Setting theremarksReporting property is equivalent to callingsetRemarksReporting.
Setting thedefaultBatchValue property is equivalent to callingsetDefaultExecuteBatch
See Also:
"Oracle Update Batching"The following example shows how to use theput method of thejava.util.Properties class, in this case, to set Oracle performance extension parameters.
//import packages and register the driverimport java.sql.*;import java.math.*;import oracle.jdbc.*;import oracle.jdbc.pool.OracleDataSource;//specify the properties objectjava.util.Properties info = new java.util.Properties();info.put ("user", "scott");info.put ("password", "tiger");info.put ("defaultRowPrefetch","20");info.put ("defaultBatchValue", "5");//specify the datasource object OracleDataSource ods = new OracleDataSource();ods.setURL("jdbc:oracle:thin:@//myhost:1521/orcl");ods.setUser("scott");ods.setPassword("tiger");ods.setConnectionProperties(info);...Database URLs are strings. The complete URL syntax is:
jdbc:oracle:driver_type:[username/password]@database_specifier
Note:
The brackets indicate that theusername/password pair is optional.
kprb, the internal server-side driver, uses an implicit connection. Database URLs for the server-side driver end after thedriver_type.
The first part of the URL specifies which JDBC driver is to be used. The supporteddriver_type values arethin,oci, andkprb.
The remainder of the URL contains an optional user name and password separated by a slash, an @, and thedatabase specifier, which uniquely identifies the database to which the application is connected. Some database specifiers are valid only for the JDBC Thin driver, some only for the JDBC OCI driver, and some for both.
Table 8-3, shows the possible database specifiers, listing which JDBC drivers support each specifier.
Note:
Starting Oracle Database 10g, Oracle Service IDs are not supported.
Starting Oracle Database 10g, Oracle no longer supports Oracle Names as a naming method.
Table 8-3 Supported Database Specifiers
| Specifier | Supported Drivers | Example |
|---|---|---|
Oracle Net connection descriptor | Thin, OCI | Thin, using an address list: url="jdbc:oracle:thin:@(DESCRIPTION= (LOAD_BALANCE=on)(ADDRESS_LIST= (ADDRESS=(PROTOCOL=TCP)(HOST=host1) (PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=host2)(PORT=1521))) (CONNECT_DATA=(SERVICE_NAME=service_name)))" OCI, using a cluster: "jdbc:oracle:oci:@(DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=cluster_alias) (PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=service_name)))" |
Thin-style service name | Thin | Refer to"Thin-style Service Name Syntax" for details. "jdbc:oracle:thin:scott/tiger@//myhost:1521/myservicename" |
LDAP syntax | Thin | Refer toLDAP Syntax for details. |
Bequeath connection | OCI | Empty. That is, nothing after @ "jdbc:oracle:oci:scott/tiger/@" |
TNSNames alias | Thin, OCI | Refer to"TNSNames Alias Syntax" for details. |
Thin-style Service Name Syntax
Thin-style service names are supported only by the JDBC Thin driver. The syntax is:
@//host_name:port_number/service_name
For example:
jdbc:oracle:thin:scott/tiger@//myhost:1521/myservicename
You can find the availableTNSNAMES entries listed in thetnsnames.ora file on the client computer from which you are connecting. On Windows, this file is located in theORACLE_HOME\NETWORK\ADMIN directory. On UNIX systems, you can find it in theORACLE_HOME directory or the directory indicated in yourTNS_ADMIN environment variable.
For example, if you want to connect to the database on hostmyhost as userscott with passwordtiger that has aTNSNAMES entry ofMyHostString, then write the following:
OracleDataSource ods = new OracleDataSource();ods.setTNSEntryName("MyTNSAlias");ods.setUser("scott");ods.setPassword("tiger");ods.setDriverType("oci");Connection conn = ods.getConnection();Theoracle.net.tns_admin system property must be set to the location of thetnsnames.ora file so that the JDBC Thin driver can locate thetnsnames.ora file. For example:
System.setProperty("oracle.net.tns_admin", "c:\\Temp");String url = "jdbc:oracle:thin:@tns_entry";Note:
When using TNSNames with the JDBC Thin driver, you must set theoracle.net.tns_admin property to the directory that contains yourtnsnames.ora file.java -Doracle.net.tns_admin=$ORACLE_HOME/network/admin
An example of database specifier using the Lightweight Directory Access Protocol (LDAP) syntax is as follows:
"jdbc:oracle:thin:@ldap://ldap.acme.com:7777/sales,cn=OracleContext,dc=com"
When using SSL, change this to:
"jdbc:oracle:thin:@ldaps://ldap.acme.com:7777/sales,cn=OracleContext,dc=com"
Note:
The JDBC Thin driver can use LDAP over SSL to communicate with Oracle Internet Directory if you substituteldaps: forldap: in the database specifier. The LDAP server must be configured to use SSL. If it is not, then the connection attempt will hang.The JDBC Thin driver supports failover of a list of LDAP servers during the service name resolution process, without the need for a hardware load balancer. Also, client-side load balancing is supported for connecting to LDAP servers. A list of space separated LDAP URLs syntax is used to support failover and load balancing.
When a list of LDAP URLs is specified, both failover and load balancing are enabled by default. Theoracle.net.ldap_loadbalance connection property can be used to disable load balancing, and theoracle.net.ldap_failover connection property can be used to disable failover.
An example, which uses failover, but with client-side load balancing disabled, is as follows:
Properties prop = new Properties();String url = "jdbc:oracle:thin:@ldap://ldap1.acme.com:3500/cn=salesdept,cn=OracleContext,dc=com/salesdb " +"ldap://ldap2.acme.com:3500/cn=salesdept,cn=OracleContext,dc=com/salesdb " +"ldap://ldap3.acme.com:3500/cn=salesdept,cn=OracleContext,dc=com/salesdb";prop.put("oracle.net.ldap_loadbalance", "OFF" );OracleDataSource ods = new OracleDataSource();ods.setURL(url);ods.setConnectionProperties(prop);The JDBC Thin driver supports LDAP nonanonymous bind. A set of JNDI environment properties, which contains authentication information, can be specified for a data source. If a LDAP server is configured as not allowing anonymous bind, then authentication information must be provided to connect to the LDAP server. The following example shows a simple clear-text password authentication:
String url = "jdbc:oracle:thin:@ldap://ldap.acme.com:7777/sales,cn=salesdept,cn=OracleContext,dc=com";Properties prop = new Properties();prop.put("java.naming.security.authentication", "simple");prop.put("java.naming.security.principal","cn=salesdept,cn=OracleContext,dc=com");prop.put("java.naming.security.credentials", "mysecret");OracleDataSource ods = new OracleDataSource();ods.setURL(url);ods.setConnectionProperties(prop);Since JDBC passes down the three properties to JNDI, the authentication mechanism chosen by client is consistent with how these properties are interpreted by JNDI. For example, if the client specifies authentication information without explicitly specifying thejava.naming.security.authentication property, then the default authentication mechanism is "simple". Please refer to relevant JDNI documentation for details.