
Октябрь/Ноябрь 2003
Профессионалу разработчику
Простые стратегии для сложных данных:
объектно-реляционная технология Oracle9i
(Окончание)
(Simple Strategies for Complex Data:
Object-Relational Technology Oracle9i)
Источник: Geoff Lee и др. An Oracle Technical White Paper, май 2002.
http://otn.oracle.com/products/oracle9i/pdf/simple_strat_for_complex_rel2.pdf
Перевод Алексея Резниченко
Начало перевода данной статьи опубликовано в предыдущем выпуске OM/RE за август-сентябрь 2003г.
Предисловие редакторов русского перевода
В данном документе четко и лаконично изложены основные принципы объектно-
реляционной технологии, воплощенной в новом продукте компании Oracle – в сервере баз
данных Oracle9i. Редакция журнала считает необходимым познакомить с ним читателей.
Вместе с тем, подготовка и публикация перевода этого документа была в определенной
степени инициирована также терминологической дискуссией, сопровождавшей перевод
на русский язык документации Oracle9i, который выполнялся специалистами компаний
РДТЕХ (www.rdtex.ru) и ITI Ltd. (www.iti.ru). Некоторые фрагменты этой дискуссии
отражены в последних публикациях колонки "О чистоте русского языка и точности
терминологии". В ходе дискуссии ее участники неоднократно указывали на вольности с
терминологией в документации Oracle. В отличие от документации Oracle9i данный
документ безупречен в части терминологии.
К сожалению, авторы документа не приводят никаких сведений о соотношении
объектных возможностей, предусмотренных в Oracle 9i и в стандартах SQL:1999, а также
SQL:200n – новой версии международного официального стандарта языка SQL,
разработка которой завершается в настоящее время.
Все стандарты, на которые имеются ссылки в данном документе, подробно рассмотрены в
книге М.Р.Когаловского "Энциклопедия технологий баз данных" (М: "Финансы и
статистика", 2002). Там же содержатся необходимые ссылки на соответствующие
официальные документы и другие публикации, включая отечественные. Кроме того,
полезные публикации по затрагиваемым в статье вопросам указываются в примечаниях
редакторов перевода.
В данном выпуске журнала публикуется окончание перевода статьи.
Для удобства читателя в обоих случаях приводится полное содержание статьи и литературные
ссылки к русскому переводу.
Анатолий Бачин (omre@mail.ru),
Михаил Когаловский (kogalov@cemi.rssi.ru),
Александр Соколов (ap_sokolov@mail.ru)
СОДЕРЖАНИЕ
Часть I
Введение
- Объектно-ориентированная разработка приложений
- Система объектных типов СУБД Oracle9i
- Объектные типы
- Объектные представления
- Наследование
- Типы-коллекции
- Ссылочные типы
- Большие объекты
- Определяемые пользователями конструкторы
- Синонимы типов
- Эволюция типов
- Ссылки к русскому переводу
Часть II
Связывания для языков программирования
Полная поддержка объектно-реляционной системы типов Oracle доступна в связываниях для ряда языков программирования, включая PL/SQL, Java и C/C++. К экземплярам типов можно получить доступ, и с ними можно манипулировать через интерфейсы прикладного программирования, такие, как JDBC (Java DataBase Connectivity) и OCCI (Oracle C++ Call Interface). Корпорация Oracle предоставляет также инструменты, подобные утилите JPublisher и транслятору объектных типов Object Type Translator (OTT), для отображения иерархий объектных типов в языки Java и C++. Кроме того, в средах этих языков также поддерживается подстановочность экземпляров и ссылок REF.
(Прим. ред. О связывании для языков программирования (language binding) в объектных СУБД, соответствующих стандарту объектных баз данных ODMG, см. например, [5]. О спецификациях связывания SQL для объектных языков программирования, принятых в октябре 2000 г., см. например, [6].)
Отображение объектов между SQL и Java
Интерфейсы JDBC и SQLJ, утилита JPub
|
В СУБД Oracle объектно-реляционные возможности тесно интегрированы со средой Java с помощью стандартных интерфейсов прикладного программирования JDBC и SQLJ. |
Объектно-реляционные возможности предоставляют более естественный и продуктивный способ для поддержания согласованной структуры набора Java-классов на уровне приложения и модели данных на уровне хранения данных. В СУБД Oracle объектно-реляционные возможности тесно интегрированы со средой Java с помощью стандартных интерфейсов прикладного программирования JDBC и SQLJ. Объектные типы SQL могут быть отображены в Java-классы. Утилита JPublisher (JPub) автоматически генерирует файлы для JDBC или SQLJ с определениями Java-классов, реализующих эти отображения. Каждый сгенерированный Java-класс содержит определенные для него методы чтения состояния объектов с сервера базы данных и записи состояния на сервер. В свою очередь, Java-приложения могут использовать эти сгенерированные Java-классы для сохранения объектов в базе данных и их выборки из базы.
(Прим. ред. О стандарте JDBC см. например, [7]. О спецификациях SQLJ см. например, [8].)
Далее представлены фрагменты кода Java-класса, сгенерированные утилитой JPub.
// Создать Java-класс, который реализует интерфейс SQLData
public class JPurchaseOrder implements SQLData
{
…
public void readSQL (SQLInput stream, String typeName)
throws SQLException {…}
public void writeSQL (SQLOutput stream)
throws SQLException {…}
…
}
-
Этот Java-класс JPurchaseOrder может быть далее использован в следующей Java-программе для выборки объектов из базы данных.
// Экземпляры объекта можно рассматривать как Java-объекты
ResultSet rs = stmt.executeQuery("select value(p) from
purchase_order_tab p");
rs.next();
JPurchaseOrder jp = (JPurchaseOrder) rs.getObject(1);
String streetName = jp.shipAddr.street;
Объектные типы в SQLJ
В СУБД Oracle9i введена возможность "бесшовно" отображать заданный Java-класс в некоторый объект SQL. Согласно части 2 стандарта SQLJ, SQLJ Object Types (Объектные типы SQLJ), определяется отображение между некоторым объектом SQL и соответствующей реализацией Java-класса. Спецификации SQLJ Object Types находятся в процессе стандартизации в качестве расширения стандарта SQL:99. (Прим. ред. В июле 2002 г. указанное расширение стандарта SQL:1999 было принято в качестве части 13 этого стандарта под названием SQL/JRT, где аббревиатура JRT расшифровывается как Java Routines and Types.)
Рассмотрим следующий пример:
CREATE TYPE ADDRESS_T AS OBJECT EXTERNAL NAME "Address"
LANGUAGE JAVA USING SQLDATA (
STREET VARCHAR(50) EXTERNAL NAME "street",
ZIP_CODE VARCHAR(10) EXTERNAL NAME "zip",
STATIC FUNCTION GET_CITY (VARCHAR zip) RETURN VARCHAR
EXTERNAL NAME "get_city(java.lang.String)
RETURN java.lang.String",
STATIC FUNCTION GET_STATE (VARCHAR zip) RETURN VARCHAR
EXTERNAL NAME "get_state(java.lang.String)
RETURN java.lang.String",
MEMBER FUNCTION CITY RETURN VARCHAR EXTERNAL NAME "getCity()
RETURN java.lang.String",
MEMBER FUNCTION STATE RETURN VARCHAR EXTERNAL NAME
"getState() RETURN java.lang.String");
В данном примере в операторе CREATE TYPE предложение EXTERNAL NAME специфицирует внешнее имя, которое определяет Java-класс, используемый в реализации. Предложение USING специфицирует интерфейс, используемый для доступа к состоянию объекта.
Для каждого атрибута данного объектного типа необязательное предложение EXTERNAL NAME задает имя соответствующего Java-поля. Для методов предложение EXTERNAL NAME определяет имя соответствующей Java-функции и ее сигнатуру.
Приведенная выше информация об отображении хранится как часть метаданных данного типа. Она обеспечивает "бесшовный" доступ к объектам SQL из Java через JDBC, не требуя от пользователя явного применения интерфейса SQLData или регистрации этого класса с помощью отображения типов Java (Java typemap).
Иерархия объектных типов в SQLJ может быть отображена в иерархию наследования Java. Диспетчеризация методов, включая переопределение этих типов, осуществляется в процессе исполнения Java-программы.
Отображение объектов SQL в C++
Интерфейс уровня вызовов Oracle для C++ (Oracle C++ Call Interface, OCCI) специфицирует отображение объектных типов в C++. Таким образом, можно получить доступ к экземплярам объектных типов в базе данных, и их можно модифицировать из объектов C++ в приложении. Навигационный интерфейс OCCI позволяет получать доступ к объектно-реляционным данным и модифицировать их как объекты C++ без явного использования SQL.
Транслятор объектных типов Object Types Translator (OTT) генерирует по умолчанию классы C++, соответствующие объектным типам, включая иерархии типов. Он также предоставляет по умолчанию реализации методов, необходимых для чтения объектов из базы данных и их записи в базу данных.
Для примера рассмотрим следующую иерархию объектных типов:
CREATE TYPE Person AS OBJECT (name VARCHAR2(100), age NUMBER)
NOT FINAL;
CREATE TYPE Student UNDER Person(dept VARCHAR2(50), advisor REF
Person);
Далее приведены классы C++, сгенерированные OTT для этой иерархии типов. Класс OCCIPObject предоставляется интерфейсом OCCI как базовый класс для классов, обладающих сохраняемыми (persistent) или временными объектами.
class Person : public OCCIPObject { …
void *operator new(size_t size, const OCCIConnection& con,
const OCCIString& table);
static void readSQL(const OCCIAnyData& stream, Person *obj);
static void writeSQL(const Person *obj, OCCIAnyData& stream);
…}
class Student : public Person {…
static void readSQL(const OCCIAnyData& stream, Student *obj);
static void writeSQL(const Student *obj, OCCIAnyData&
stream); …}
Фрагменты кода, соответствующие двум методам, приведены ниже:
void Person::readSQL(const OCCIAnyData& stream, Person *obj){
obj->name = stream.getString(1);
obj->age = stream.getNumber(2); }
void Student::readSQL(const OCCIAnyData& stream, Student *obj) {
Person::readSQL(stream, obj);
obj->dept = stream.getString(3);
obj->advisor = stream.getRef(4); }
Таблица отображения типов поддерживает ассоциацию между именами типов SQL и именами классов C++, и она используется во время исполнения для определения класса, чьи подпрограммы readSQL и writeSQL должны быть вызваны. OTT также обеспечивает для пользователей гибкость расширения сгенерированных классов для добавления дополнительных выполняемых функций.
Следующий фрагмент кода иллюстрирует выборку объекта SQL в экземпляре класса C++:
OCCIResultSet *resultSet =
stmt->executeQuery("select VALUE(p) from person_tab p where
name = "Joe"");
/* выборка объекта создает соответствующий экземпляр класса */
Student *joe = (Student *)resultSet.getObject(1);
/* dereferencing the REF value yields the object */
Person *joe_advisor = joe->advisor->ptr();
|