Java и данные из Oracle - все очень просто

Владимир Пржиялковский

Содержание

Взаимодействие с базой данных через JDBC

Общение программ на Java с данными в БД под управлением Oracle осуществляется двумя основными способами: через JDBC и через SQLJ.

Использование JDBC

JDBC и JDBC-драйверы

JDBC - это Java API (Application Program Interface) для доступа из Java-программ к SQL-СУБД разных типов. Подразумевается, что одна и та же Java-программа сумеет с помощью JDBC реально работать в среде Windows с данными mySQL или же в среде Solaris с данными Informix. Она же может быть хранимой процедурой в БД под Oracle и работать с данными той же Oracle или, к примеру, Sybase.

Реализуется JDBC в виде интерфейсов java.sql (основной) и javax.sql (расширенный). Конкретный набор классов, реализующий JDBC-интерфейс и осуществляющий доступ к конкретной СУБД, называется драйвером. JDBC-драйверы для своих СУБД поставляют все основные разработчики.

Описаниями JDBC определено четыре типа JDBC-драйверов: два "тонких" и два "толстых".

  • Соединительный драйвер JDBC (тип I, "толстый")
  • "Родной" API-драйвер (тип II "толстый")
  • Общий сетевой API-драйвер (тип III "частично тонкий")
  • Драйвер прямого доступа через разъем (тип IV "тонкий")

JDBC-драйверы в Oracle

Фирма Oracle поставляет для работы со своей СУБД следуюшие драйверы, удовлетворяющие спецификациям JDBC:

  • тонкий (thin; тип IV, для работы извне, через браузер, по TCP/IP)
  • толстый (thick; тип II, для локальной работы извне)
  • родной (тип II, для работы изнутри, из хранимых в БД Java-процедур)

Помимо этого около сотни разных фирм поставляют JDBC-драйверы собственной реализации типов I, II, III и IV, в том числе и для связи с Oracle. Они доступны в интернете.

Установка JDBC-драйверов для работы с Oracle

Пакет java.sql с классами JDBC, реализованными фирмой Oracle в соответствии с интерфейсами, предлагаемыми фирмой Sun, входит в состав стандартного JDK. Тонкий драйвер входит в состав файла classes111.zip, или его более поздней версии classes12.zip. При отсутствии на компьютере его можно получить по адресу download.oracle.com/otn/utilities_drivers/jdbc/817/classes12.zip (версия 8.1.7).

Толстый драйвер можно получить по адресу download.oracle.com/otn/utilities_drivers/jdbc/817/jdbc817jdk12-nt.zip (для NT) или download.oracle.com/otn/utilities_drivers/jdbc/817/jdbc817jdk12-sol.zip (для Solaris).

Для работы с драйверами нужно добавить путь к этим файлам к переменной среды окружения CLASSPATH.

Файл Java-программы для проверки связи через JDBC

Для следующих ниже примеров организации разных вариантов связи с БД через JDBC нужно подготовить файл StaffByJDBC.java с общим для всех примеров текстом:

import java.sql.*;
import oracle.jdbc.driver.*;

public class StaffByJDBC
{
     public static void main(String[] args)
     {
          String url = null;

           if (args.length > 0) {
           if (args[0].compareToIgnoreCase("thin") == 0) {
                 url = "jdbc:oracle:thin:@localhost:1521:TEACHER";
          }
          else if (args[0].compareToIgnoreCase("oci") == 0) {
                url = "jdbc:oracle:oci8:@TEACHER";
          }
          else if (args[0].compareToIgnoreCase("kprb") == 0) {
               url = "jdbc:oracle:kprb:";
}
}

if (url == null) {
System.out.println("usage: StaffByJDBC [thin/oci]");
return;
}

try {
    DriverManager.registerDriver (
        new oracle.jdbc.driver.OracleDriver());

}
catch (Exception e) { return; }

try {
Connection cn =
            DriverManager.getConnection (url,"scott","tiger");

Statement st = cn.createStatement();
ResultSet rs =
                st.executeQuery ("SELECT empno, ename FROM emp");

while (rs.next()) {
     System.out.println("Number=" + rs.getString(1) + " " +
                             "Name=" + rs.getString(2));
}

st.close();
cn.close();

}
catch (Exception e) { return; }
finally { System.out.println("All that happened"); }
}
}

Работа с данными Oracle из внешних Java-программ

Работа с Oracle через тонкий драйвер

Трансляция и запуск программы (среда Unix - аналогично):

SET CLASSPATH=%ORACLE_HOME%\jdbc\lib\classes12.zip;.

javac StaffByJDBC.java

java StaffByJDBC thin

Работа с Oracle через толстый OCI-драйвер

Трансляция и запуск программы (среда Unix - аналогично):

SET CLASSPATH=%ORACLE_HOME%\jdbc\lib\classes12.zip;.

javac StaffByJDBC.java

java StaffByJDBC oci

Работа с данными Oracle из хранимых Java-программ

Обращение к БД из хранимых процедур

Загрузка, трансляция и запуск программы:

loadjava -user scott/tiger -oci8 -r StaffByJDBC.java

sqlplus scott/tiger

SQL> ALTER JAVA SOURCE "StaffByJDBC" COMPILE;

Java altered.

SQL> ALTER JAVA CLASS "StaffByJDBC" COMPILE;

Java altered.

SQL> CREATE OR REPLACE PROCEDURE liststaff (drivertype IN VARCHAR2)
AS LANGUAGE JAVA
NAME 'StaffByJDBC.main (java.lang.String[])';
/

Function created.

SQL> EXEC liststaff('kprb')

PL/SQL procedure successfully completed.

Просмотр результатов - в трассировочном файле в каталоге ОС udump.

Особенности работы с kprb-драйвером

Работа с kprb-драйвером имеет свои отличия по отношению к работе со внешними драйверами:

  1. для хранимых программ явного подсоединения с БД не требуется - kprb-драйвер выполняет его неявно автоматически (код явного соединения из программ, написанных из расчета на внешнее соединение, будет проигнорирован)
  2. так как драйвер kprb не поддерживает AUTOCOMMIT, выполнять COMMIT или ROLLBACK в программе нужно явно
  3. устройством выдачи Sys.output по умолчанию является для kprb не экран, а трассировочные файлы в каталоге udump

Обращение к данным из триггеров Oracle

Специальных Java-триггеров в Oracle нет, и поэтому организация триггера на Java требует заведения внешней "оболочки" на PL/SQL, внутри которой делаются обращения к процедурам на Java, опубликованным для PL/SQL.

Вот как это может выглядеть:

CREATE TRIGGER scott.salary_check
BEFORE INSERT OR UPDATE OF sal, job ON scott.emp
FOR EACH ROW
WHEN (new.job <> 'PRESIDENT')
CALL check_sal(:new.job, :new.sal, :new.name);
/

Здесь CHECK_SAL должна быть опубликованной процедурой на Java.

Взаимодействие с базой данных через SQLJ

SQLJ представляет собой альтернативный JDBC способ работы с БД из Java-программ, использующий схему включающего языка/предкомпиляции. В отличие от JDBC, SQLJ позволяет использовать в программе только статические SQL-обращения к базе, однако исходный текст программ может выглядеть много компактнее.

Подобно Java-программам с JDBC, программы с SQLJ могут работать как на клиенте, так и на сервере.

SQLJ стандартизован комитетом ANSI. Более подробно о нем см. на web-узле консорциума SQLJ http://www.sqlj.org/.

Пример программы с использованием SQLJ

Типовой пример программы с использованием SQLJ (файл StaffBySQLJ.sqlj ):

import java.sql.*;
import sqlj.runtime.ref.DefaultContext;
import oracle.sqlj.runtime.Oracle;

#sql iterator MyIter (String ename, int empno, float sal);

public class StaffBySQLJ
{
       public static void main (String args[]) throws SQLException
       {
             Oracle.connect
                    ("jdbc:oracle:thin:@localhost:1521:teacher",
                    "scott", "tiger");

            MyIter iter;
           #sql iter={ select ename, empno, sal from emp };
           while (iter.next()) {

                    System.out.println
                           (iter.ename()+" "+iter.empno()+" "+iter.sal());
               }
         }
}

Транслирование программы с SQLJ

Пример транслирования программы с SQLJ:

SET CLASSPATH=%ORACLE_HOME%\jdbc\lib\classes12.zip;.
SET CLASSPATH=%CLASSPATH%;%ORACLE_HOME%\sqlj\lib\translator.zip
SET CLASSPATH=%CLASSPATH%;%ORACLE_HOME%\sqlj\lib\runtime12.zip

sqlj StaffBySQLJ.sqlj

После этого в текущем каталоге появятся файлы (вариант версии 8.1.7):

StaffBySQLJ.class
StaffBySQLJ.java
StaffBySQLJ _SJProfile0.ser
StaffBySQLJ _SJProfileKeys.class
MyIter.class

Таким образом, программа sqlj не только предтстранслирует исходный яайл SQLJexample.sqlj, но и странслирует вслед порожденную ею же программу SQLJexample.java с учетом подготовленных свойств. Запуск конечного результата выглядит как обычно:

java StaffBySQLJ

Более сложный пример транслирования:

sqlj -user=scott/tiger@jdbc:oracle:thin:@localhost:1521:teacher StaffBySQLJ.sqlj

Транслирование программ с SQLJ, предназначенных для исполнение на сервере, можно осуществлять

(а) явно (программа sqlj, как показано выше) с последующей загрузкой классов в БД (в этом случае их перед загрузкой удобно объединять в jar-файлы)
(б) неявно, путем загрузки файлов .sqlj в БД (автоматическая предтрансляция будет в этом случае выполнена.внутренними средствами Oracle).

Выполнение программы с SQLJ

Для возможности обращения программы c SQLJ, загруженной с помощью loadjava из jar-файла (или напрямую), можно выполнить

CREATE OR REPLACE PROCEDURE my_sqlj_example
AS LANGUAGE JAVA
NAME 'StaffBySQLJ.main(java.lang.String[])';

Программы с SQLJ, написанные для работы с БД извне (с клиентской стороны), всегда будут работоспособны и в качестве хранимых программ (то есть, на сервере). Обратное не обязательно верно (см. комментарий по поводу особенностей использования kprb-драйвера выше).

Ссылки по теме

Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=1772