2003 г
Java и данные из Oracle - все очень просто
© Владимир
Пржиялковский,
координатор Евро-Азиатской Группы Пользователей Oracle,
преподаватель УКЦ Interface
Ltd.
Взаимодействие с базой данных через 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-драйвером имеет свои отличия по отношению к работе со внешними
драйверами:
- для хранимых программ явного подсоединения с БД не требуется - kprb-драйвер
выполняет его неявно автоматически (код явного соединения из программ, написанных
из расчета на внешнее соединение, будет проигнорирован)
- так как драйвер kprb не поддерживает AUTOCOMMIT, выполнять COMMIT или ROLLBACK
в программе нужно явно
- устройством выдачи 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-драйвера выше).
Дополнительная информация
За дополнительной информацией обращайтесь в компанию Interface Ltd.