2 JDBC、UCPおよびデータベースにおけるJavaの簡単な紹介
Oracle Databaseは、データの格納、変更および使用に使用できるリレーショナル・データベースです。
Javaアプリケーションでは、リレーショナル・データベースのデータのアクセスおよび操作に、Java Database Connectivity(JDBC)標準が使用されます。
業界標準のアプリケーション・プログラミング・インタフェース(API)であるJDBCを使用すると、JavaからSQLを使用してRDBMSにアクセスできます。JDBCは、JDBCエスケープ標準のエントリ・レベルに準拠しています。ベンダー各社はそれぞれ独自の拡張を含めたJDBC仕様を実装しています。
ユニバーサル接続プール(UCP)は、接続を再利用するためにデータベース接続オブジェクトをキャッシュするために使用する接続プールです。これにより、パフォーマンスが向上します。
データベースにおけるJava(OJVM)により、Javaデータ・ロジックを使用してSQL操作をグループ化し、インプレース処理用にデータベースにロードできます。
この章では、Oracle Database 12cリリース2(12.2)とともにJDBCドライバ、ユニバーサル接続プール(UCP)およびデータベースにおけるJava(OJVM)について説明します
- Java Database Connectivityドライバ(JDBC)
-
ユニバーサル接続プール(UCP)
-
データベースにおけるJava(OJVM)
Java Database Connectivityドライバ(JDBC)
JDBCは、ユーザーがデータベースに接続してSQL文を実行し、データベースに問合せできるようにするデータベース・アクセス・プロトコルです。JDBCドライバは、最新のJDBC仕様に準拠して実装されています。Javaアプリケーションは、クラスパスにJDK8と互換性のあるojdbc8.jar
が必要です。
コアJavaクラス・ライブラリには、JDBC APIのjava.sql
とjavax.sql
が用意されています
次の項では、JDBC標準に対するOracleサポートについて説明します。
-
Oracle JDBC Thinドライバ
-
Oracle JDBCパッケージ
Oracle JDBC Thinドライバ
ほとんどの場合、JDBC Thinドライバを使用することをお薦めします。JDBC Thinドライバは、適切なJava仮想マシンを搭載したシステムであれば、どのシステム上でも機能します。(JVM)Oracleが提供する他のクライアント・ドライバとして、JDBC Thinドライバ、Oracle Call Interface (OCI)ドライバ、サーバー側Thinドライバ、サーバー側内部ドライバなどがあります。
JDBC Thinドライバは、Pure JavaのType IVドライバです。JDBCドライバ・バージョン(ojdbc8.jar)には、JDK 8のサポートが含まれています。
JDBC Thinドライバは、データベースにアクセスするためにSQL*Netを使用してサーバーと通信します。
関連項目:
『Oracle Database JDBC開発者ガイド』アクション・アイテム1: DB_URLを変更してデータベースを指すようにします。ヘルプが必要な場合は、GithubのDataSourceSample.javaを参照してください。
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.DatabaseMetaData;
import oracle.jdbc.pool.OracleDataSource;
import oracle.jdbc.OracleConnection;
public class DataSourceSample {
// The recommended format of a connection URL is the long format with the
// connection descriptor.
// final static String DB_URL= "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(HOST=myhost)(PORT=1521)(PROTOCOL=tcp))(CONNECT_DATA=(SERVICE_NAME=myorcldbservicename)))";
final static String DB_URL= "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(HOST=slc07qwu.us.oracle.com)(PORT=5521)(PROTOCOL=tcp))(CONNECT_DATA=(SERVICE_NAME=jvma.regress.rdbms.dev.us.oracle.com)))";
final static String DB_USER = "hr";
final static String DB_PASSWORD = "hr";
public static void main (String args[]) throws SQLException {
OracleDataSource ods = new OracleDataSource();
ods.setURL(DB_URL);
ods.setUser(DB_USER);
ods.setPassword(DB_PASSWORD);
// With AutoCloseable, the connection is closed automatically.
try (OracleConnection connection = (OracleConnection)
ods.getConnection()) {
// Get the JDBC driver name and version
DatabaseMetaData dbmd = connection.getMetaData();
System.out.println("Driver Name: " + dbmd.getDriverName());
System.out.println("Driver Version: " +
dbmd.getDriverVersion());
System.out.println("Database Username is: " +
connection.getUserName());
}
}
}
ユニバーサル接続プール
接続プールは、接続オブジェクトを再利用して、接続オブジェクトが作成される回数を減らすことで、パフォーマンスを向上させます。
Oracle Universal Connection Pool (UCP)は、Oracle Database構成との密接な統合を利用して、高可用性、スケーラビリティ、ロード・バランシングとともに接続プール機能を提供する、機能豊富なJava接続プールです。
UCPを使用するには、Javaアプリケーションまたはコンテナのクラスパスにucp.jar
とojdbc8.jar
(JDK8)が必要です。
関連項目:
Oracle Universal Connection Pool開発者ガイドアクション・アイテム2: DB_URLを変更してデータベースを指すようにします。詳細は、GithubでUCPSampleを参照することもできます。
Import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import oracle.ucp.jdbc.PoolDataSourceFactory;
import oracle.ucp.jdbc.PoolDataSource;
public class UCPSample {
// final static String DB_URL= "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(HOST=myhost)(PORT=1521)(PROTOCOL=tcp))(CONNECT_DATA=(SERVICE_NAME=myorcldbservicename)))";
final static String DB_USER = "hr";
final static String DB_PASSWORD = "hr";
final static String CONN_FACTORY_CLASS_NAME = "oracle.jdbc.pool.OracleDataSource";
/*
* The sample demonstrates UCP as client side connection pool.
*/
public static void main(String args[]) throws Exception {
// Get the PoolDataSource for UCP
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();
// Set the connection factory first before all other properties
pds.setConnectionFactoryClassName(CONN_FACTORY_CLASS_NAME);
pds.setURL(DB_URL);
pds.setUser(DB_USER);
pds.setPassword(DB_PASSWORD);
pds.setConnectionPoolName("JDBC_UCP_POOL");
// Default is 0. Set the initial number of connections to be
// created when UCP is started.
pds.setInitialPoolSize(5);
// Default is 0. Set the minimum number of connections
// that is maintained by UCP at runtime.
pds.setMinPoolSize(5);
// Default is Integer.MAX_VALUE (2147483647). Set the maximum
// number of connections allowed on the connection pool.
pds.setMaxPoolSize(20);
// Default is 30secs. Set the frequency in seconds to enforce
// the timeout properties. Applies to
// inactiveConnectionTimeout(int secs),
// AbandonedConnectionTimeout(secs)&
//TimeToLiveConnectionTimeout(int secs).
// Range of valid values is 0 to Integer.MAX_VALUE.
pds.setTimeoutCheckInterval(5);
// Default is 0. Set the maximum time, in seconds, that a
// connection remains available in the connection pool.
pds.setInactiveConnectionTimeout(10);
System.out.println("Available connections before checkout: "
+ pds.getAvailableConnectionsCount());
System.out.println("Borrowed connections before checkout: "
+ pds.getBorrowedConnectionsCount());
// Get the database connection from UCP.
try (Connection conn = pds.getConnection()) {
System.out.println("Available connections after checkout: "
+ pds.getAvailableConnectionsCount());
System.out.println("Borrowed connections after checkout: "
+ pds.getBorrowedConnectionsCount());
// Perform a database operation
printEmployees(conn);
} catch (SQLException e) {
System.out.println("UCPSample - " + "SQLException occurred : "
+ e.getMessage());
}
System.out.println("Available connections after checkin: "
+ pds.getAvailableConnectionsCount());
System.out.println("Borrowed connections after checkin: "
+ pds.getBorrowedConnectionsCount());
}
/*
* Displays first_name and last_name from the employees table.
*/
public static void printEmployees(Connection connection)
throws SQLException {
// Statement and ResultSet are AutoCloseable and closed
// automatically.
try (Statement statement = connection.createStatement()) {
try (ResultSet resultSet = statement
.executeQuery("select first_name, last_name from
employees")) {
System.out.println("FIRST_NAME" + " " + "LAST_NAME");
System.out.println("---------------------");
while (resultSet.next())
System.out.println(resultSet.getString(1) + " "
+ resultSet.getString(2) + " ");
}
}
}
}
データベースにおけるJava(OJVM)
Oracle Databaseには、サーバーに常駐するJava仮想マシン(JVM)があります。それによって、サーバー上のOracle JVM内で実行中のJavaアプリケーションから、同じシステムおよび同じプロセスに存在するデータにアクセスできます。
データ処理が大きいアプリケーションには、データベースにおけるJavaをお薦めします。JVMは、基礎となるOracle RDBMSライブラリを直接使用する機能があり、JavaコードとSQLデータの間にネットワーク接続が必要ありません。そのため、パフォーマンスと実行が向上します。データ・アクセスのために、サーバー上でJavaコードを実行するとき、Oracle Databaseはサーバー側内部ドライバを使用します。
アクション・アイテム3: SQLPlusを介してデータベースに接続し、ServersideConnect.javaを起動する前にServersideConnect.sqlを実行します。詳細は、Githubのサンプルを参照してください。
ServersideConnect.sql
Rem NAME
Rem ServersideConnect.sql
Rem
Rem DESCRIPTION
Rem SQL for invoking the method which gets a server side connection to
rem Reads the content of the Java source from ServersideConnect.java
rem then compiles it
connect hr/hr
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED ServersideConnect_src AS
@ ServersideConnect.java
/
show error
rem A wrapper (a.k.a. Call Spec), to invoke Java
rem function in the database from SQL, PL/SQL, and client applications
CREATE OR REPLACE PROCEDURE ServersideConnect_proc AS
LANGUAGE JAVA NAME 'ServersideConnect.jrun ()';
/
rem running the sample
connect hr/hr
SET SERVEROUTPUT ON SIZE 10000
CALL dbms_java.set_output (10000);
execute ServersideConnect_proc;
InternalT2Server.java
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import oracle.jdbc.driver.OracleDriver;
import oracle.jdbc.pool.OracleDataSource;
public class ServersideConnect {
static public void jrun() throws SQLException {
// For testing ServersideConnect
// test("jdbc:oracle:kprb:@");
method1("jdbc:default:connection");
method2();
}
/*
* Shows using the server side Type 2 driver a.k.a KPRB driver
*/
static public void method1 (String url) throws SQLException {
Connection connection = null;
try {
// Method 1: Using OracleDataSource
OracleDataSource ods = new OracleDataSource();
ods.setURL(url);
connection = ods.getConnection();
System.out.println("Method 1: Getting Default Connection "
+ "using OracleDataSource");
// Perform database operation
printEmployees(connection);
}
}
static public void method2 () throws SQLException {
Connection connection = null;
try {
OracleDriver ora = new OracleDriver();
connection = ora.defaultConnection();
System.out.println("Method 2: Getting Default Connection "
+ "using OracleDriver");
// Perform database operation
printEmployees(connection);
}
}
/*
* Displays employee_id and first_name from the employees table.
*/
static public void printEmployees(Connection connection)
throws SQLException {
ResultSet resultSet = null;
Statement statement = null;
try {
statement = connection.createStatement();
resultSet = statement.executeQuery("SELECT employee_id, first_name"
+ " FROM employees order by employee_id");
while (resultSet.next()) {
System.out.println("Emp no: " + resultSet.getInt(1) + " Emp name: "
+ resultSet.getString(2));
}
}
catch (SQLException ea) {
System.out.println("Error during execution: " + ea);
ea.printStackTrace();
}
finally {
if (resultSet != null) resultSet.close();
if (statement != null) statement.close();
}
}
}