Objektorientierte PL/SQL-Programmierung

Werbung
Willkommen
Objektorientierte PL/SQL-Programmierung
für RDBMS
Andriy Terletskyy
Berenberg Bank
Neuer Jungfernstieg 20
20354 Hamburg
Berenberg stellt sich vor
MDV/EDV- Erfahrung
•
•
•
•
•
•
•
Zeitraum
Hardware
Datenbank
Pr. Sprache
1590 – ~ 1950
~ 1960
~ 1970
~ 1980
~ 1990
~ 1995
~ 2001
Rechenbrett
Buchungsautomaten
NCR Century 201
NCR 8000/9800
NCR 3600
NCR S-50
Sun 3800 Cluster
Karteikarten
Karteikarten
MIDAS
TOTAL
Supra PDM
Oracle 8.0
Oracle 8.1 - 9.2
Neat
Cobol
Cobol
Cobol
PL/SQL, Java
Modellierung
Traditionelle ODBMS
Virtuelle ODBMS auf
Basis RDBMS
BO-TYPES
OBJECT TYPES
OO-ROWTYPES
ODBMS
RDBMS
Aufbau traditionelle ODBMS
Aufbau
• Definition Basis Typen
• Abbildung Real-Welt Objekten in BOTypen
• Aufbau OO-Tabellen
OBJECT TYPES
Verwendung
• übliche DML- Anweisungen
• Datennormalisierung über OID
• DEREF - zieht referenzierte Object
Größter Nachteil
• Änderungsunfähig, bzw. schwerfällig
( … IS DANGLING)
ODBMS
Aufbau virtuelle ODBMS für RDBMS
BO-TYPES
OO-ROWTYPES
Aufbau
• RDBMS (neue oder bestehende)
• Aufbau OO-ROWTYPE (ROWTYPE + DML,
DEFAULT, TO_STRING, DBMS_OUTPUTMethoden, PK/UK- Konstruktoren )
• Aufbau BO- Typen (Vererbung, Aggregation,
Assoziation)
Verwendung
• Methoden statt übliche DML- Anweisungen
• Datennormalisierung über RDBMS
• PK/UK- Konstruktoren - ziehen referenzierte
Object über relationale ID (DEREF- Analogon)
Größter Nachteil
• Aufwandbedürftig für OO-ROWTYPE Aufbau
(Lösung : automatische Generierung oder
Herstellerimplementierung)
RDBMS
Implementierung 1/8
1.
Einführung TYPE_OBJECT – Basisklasse für alle abgeleiteten Object Types (optional)
CREATE OR REPLACE TYPE SCOTT.TYPE_OBJECT AS OBJECT(
-- attributes
object_type_name VARCHAR2(100)
-- member functions and procedures
, MEMBER FUNCTION TO_STRING RETURN VARCHAR2
, MEMBER PROCEDURE DBMS_OUTPUT
, MEMBER FUNCTION COMPARE(in_type1 TYPE_OBJECT, in_type2 TYPE_OBJECT) RETURN INTEGER
, ORDER MEMBER FUNCTION COMPARE2(in_other TYPE_OBJECT) RETURN INTEGER
) NOT FINAL NOT INSTANTIABLE
Vorteile:
• Standardisiertes Interface für alle abgeleiteten Objekte (TO_STRING, DBMS_OUTPUT)
• Einfache Übergabe abgeleiteter Typen als Parameter (Ursprungshierarchie)
• ORDER Funktion - vergleicht Instanzen wegen überschriebener COMPARE- Methode
Implementierung 2/8
2.1. Einführung OO-ROWTYPE
CREATE OR REPLACE TYPE SCOTT.ROW_DEPT UNDER SCOTT.TYPE_OBJECT(
-- attributes
deptno NUMBER(2)
, dname
VARCHAR2(14)
, loc
VARCHAR2(13)
-- constructors
, CONSTRUCTOR FUNCTION ROW_DEPT RETURN SELF AS RESULT
, CONSTRUCTOR FUNCTION ROW_DEPT( in_deptno NUMBER, in_dname VARCHAR2
, in_loc VARCHAR2) RETURN SELF AS RESULT
, CONSTRUCTOR FUNCTION ROW_DEPT(in_deptno NUMBER) RETURN SELF AS RESULT
-- member functions
, MEMBER FUNCTION ROW_EXISTS(in_deptno NUMBER) RETURN BOOLEAN
, OVERRIDING MEMBER FUNCTION COMPARE( in_type1 GLOBAL.TYPE_OBJECT
, in_type2 GLOBAL.TYPE_OBJECT) RETURN INTEGER
-- member procedures
, MEMBER PROCEDURE ROW_INSERT
, MEMBER PROCEDURE ROW_UPDATE
, MEMBER PROCEDURE ROW_MERGE
, MEMBER PROCEDURE ROW_SAVE
, MEMBER PROCEDURE ROW_DELETE
, MEMBER PROCEDURE ROW_SELECT(in_deptno NUMBER)
, MEMBER PROCEDURE ROW_DEFAULT
) NOT FINAL
Implementierung 3/8
2.1. Einführung OO-ROWTYPE
CREATE OR REPLACE TYPE SCOTT.ROW_EMP UNDER SCOTT.TYPE_OBJECT(
-- attributes
empno
NUMBER(4)
, ename
VARCHAR2(10)
, job
VARCHAR2(9)
, mgr
NUMBER(4)
, hiredate DATE
, sal
NUMBER(7,2)
, comm
NUMBER(7,2)
, deptno
NUMBER(2)
-- constructors
, CONSTRUCTOR FUNCTION ROW_EMP RETURN SELF AS RESULT
, CONSTRUCTOR FUNCTION ROW_EMP( in_empno NUMBER, in_ename VARCHAR2, in_job VARCHAR2, in_mgr NUMBER
, in_hiredate DATE, in_sal NUMBER, in_comm NUMBER, in_deptno NUMBER
) RETURN SELF AS RESULT
, CONSTRUCTOR FUNCTION ROW_EMP(in_empno NUMBER) RETURN SELF AS RESULT
-- member functions
, MEMBER FUNCTION ROW_EXISTS(in_empno NUMBER) RETURN BOOLEAN
, OVERRIDING MEMBER FUNCTION compare( in_type1 GLOBAL.TYPE_OBJECT, in_type2 GLOBAL.TYPE_OBJECT
) RETURN INTEGER
-- member procedures
, MEMBER PROCEDURE ROW_INSERT
, MEMBER PROCEDURE ROW_UPDATE
, MEMBER PROCEDURE ROW_MERGE
, MEMBER PROCEDURE ROW_SAVE
, MEMBER PROCEDURE ROW_DELETE
, MEMBER PROCEDURE ROW_SELECT(in_empno NUMBER)
, MEMBER PROCEDURE ROW_DEFAULT
) NOT FINAL
Implementierung 4/8
2.2. Einführung OO-ROWTYPE Container Types und Data-Cartridges
• Container Types
CREATE OR REPLACE TYPE TABLE_EMP AS TABLE OF SCOTT.ROW_EMP;
CREATE OR REPLACE TYPE TABLE_DEPT AS TABLE OF SCOTT.ROW_DEPT;
• Data-Cartridge für DEPT-Tabelle
CREATE OR REPLACE PACKAGE PA_DEPT IS
FUNCTION FU_SELECT RETURN TABLE_DEPT;
END;
• Data-Cartridge für EMP-Tabelle
CREATE OR REPLACE PACKAGE PA_EMP IS
FUNCTION FU_SELECT RETURN TABLE_EMP;
FUNCTION FS_DEPTNO(IN_DEPTNO IN EMP.DEPTNO%TYPE) RETURN TABLE_EMP;
FUNCTION FS_MGR(IN_MGR IN EMP.MGR%TYPE) RETURN TABLE_EMP;
END;
Implementierung 5/8
2.3. Automatische Generierung OO-ROWTYPEs, Container Types und Data-Cartridges
•
Generator (generiert, kompiliert und bewährt Sourcen)
–
Java-Klasse (liest TABLE Definition und generiert PL/SQL-Source)
–
PL/SQL Wrapper – Prozedur (ruft Java-Klasse auf)
•
DDL-Trigger (empfängt CREATE / ALTER TABLE Ereignis und schickt AQ-Message)
•
Oracle-Job (empfängt AQ-Message und anstoßt Generator )
Implementierung 6/8
3.1. Einführung BO-Types (TYPE_ MANAGER)
CREATE OR REPLACE TYPE TYPE_MANAGER UNDER ROW_EMP(
-- attributes
EMPLOYEES TABLE_EMP
-- constructors
, CONSTRUCTOR FUNCTION TYPE_MANAGER RETURN SELF AS RESULT
, CONSTRUCTOR FUNCTION TYPE_MANAGER(IN_EMPNO NUMBER) RETURN SELF AS RESULT
) NOT FINAL
Implementierung 7/8
3.2. Einführung BO-Types (TYPE_DEPARTMENT)
CREATE OR REPLACE TYPE TYPE_DEPARTMENT UNDER ROW_DEPT(
-- attributes
EMPLOYEES TABLE_EMP
-- constructors
, CONSTRUCTOR FUNCTION TYPE_DEPARTMENT RETURN SELF AS RESULT
, CONSTRUCTOR FUNCTION TYPE_DEPARTMENT(in_deptno NUMBER) RETURN SELF AS
RESULT
-- member functions
, MEMBER FUNCTION GET_MANAGER RETURN TYPE_MANAGER
) NOT FINAL
Implementierung 8/8
3.3. Einführung BO-Types (TYPE_ENTERPRISE)
CREATE OR REPLACE TYPE TYPE_ENTERPRISE UNDER TYPE_OBJECT(
-- attributes
NAME
VARCHAR2(100)
, PRESIDENT
TYPE_MANAGER
, DEPARTMENTS TABLE_DEPT
, EMPLOYEES
TABLE_EMP
-- constructors
, CONSTRUCTOR FUNCTION TYPE_ENTERPRISE RETURN SELF AS RESULT
) NOT FINAL
Programmierung 1/3
1. SQL
SQL> SELECT TYPE_DEPARTMENT(20) FROM DUAL;
TYPE_DEPARTMENT()(OBJECT_TYPE_NAME, DEPTNO, DNAME, LOC, NAME, TABLE_EMP(ROW_EMP())
-------------------------------------------------------------------------------TYPE_DEPARTMENT('TYPE_DEPARTMENT', 20, 'RESEARCH', 'DALLAS',
TABLE_EMP(
ROW_EMP('ROW_EMP', 7369, 'SMITH', 'CLERK', 7902, '17.12.80', 800, NULL, 20),
ROW_EMP('ROW_EMP', 7566, 'JONES', 'MANAGER', 7839, '02.04.81', 2975, NULL, 20),
ROW_EMP('ROW_EMP', 7788, 'SCOTT', 'ANALYST', 7566, '19.04.87', 3000, NULL, 20),
ROW_EMP('ROW_EMP', 7876, 'ADAMS', 'CLERK', 7788, '23.05.87', 1100, NULL, 20),
ROW_EMP('ROW_EMP', 7902, 'FORD', 'ANALYST', 7566, '03.12.81', 3000, NULL, 20)
)
)
SQL> SELECT VALUE(e) FROM TABLE (TYPE_MANAGER(7698).EMPLOYEES) e;
VALUE(E)(OBJECT_TYPE_NAME, EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
-------------------------------------------------------------------------------ROW_EMP('ROW_EMP', 7499, 'ALLEN', 'SALESMAN', 7698, '20.02.81', 1600, 300, 30)
ROW_EMP('ROW_EMP', 7521, 'WARD', 'SALESMAN', 7698, '22.02.81', 1250, 500, 30)
ROW_EMP('ROW_EMP', 7654, 'MARTIN', 'SALESMAN', 7698, '28.09.81', 1250, 1400, 30)
ROW_EMP('ROW_EMP', 7844, 'TURNER', 'SALESMAN', 7698, '08.09.81', 1500, 0, 30)
ROW_EMP('ROW_EMP', 7900, 'JAMES', 'CLERK', 7698, '03.12.81', 950, NULL, 30)
Programmierung 2/3
2.1. PL/SQL
DECLARE
e TYPE_ENTERPRISE := TYPE_ENTERPRISE();
BEGIN
e.dbms_output;
END;
/
DBMS Output:
SCOTT.TYPE_ENTERPRISE
( OBJECT_TYPE_NAME = TYPE_ENTERPRISE
NAME
= King Corporation
PRESIDENT
= SCOTT.TYPE_MANAGER
( OBJECT_TYPE_NAME = TYPE_MANAGER
EMPNO
= 7839
ENAME
= KING
JOB
= PRESIDENT
MGR
=
HIREDATE
= 17.11.1981 00:00:00
SAL
= 5000
COMM
=
DEPTNO
= 10
EMPLOYEES
= < SCOTT.TABLE_EMP >
)
DEPARTMENTS
= < SCOTT.TABLE_DEPT >
EMPLOYEES
= < SCOTT.TABLE_EMP >
)
Programmierung 3/6
2.2. PL/SQL
DECLARE
m TYPE_MANAGER;
BEGIN
m := TYPE_MANAGER(7839);
m.sal := m.sal * 2;
m.row_update;
m.dbms_output;
END;
/
DBMS Output:
SCOTT.TYPE_MANAGER
(
OBJECT_TYPE_NAME = TYPE_MANAGER
EMPNO
= 7839
ENAME
= KING
JOB
= PRESIDENT
MGR
=
HIREDATE
= 17.11.1981 00:00:00
SAL
= 10000
COMM
=
DEPTNO
= 10
EMPLOYEES
= < SCOTT.TABLE_EMP >
)
Zusammenfassung (virtuelle ODBMS)
•
keine Funktionalitätsverluste gegenüber der bestehenden ODBMS Lösung
•
Das Objektmodel entspricht dem relationalen Datenmodel und kann ohne
Änderung am relationalen Datenmodel erzeugt und verwendet werden
•
Vereinfachung der DML-Anweisungen
•
Zugriffe der Business Objekte (BO) sind unabhängig von der
unterliegenden Datenquelle
•
DB-Mapping für Java (JPublisher oder selbst geschriebene Generatoren)
Java DB-Mapping 1/2
1. Type-Mapping
PL/SQL-TYPE
Attribute 1
….
Attribute N
Constructor(p1,...)
Function F1(p1,..)
Procedure P2(p1,…)
Java-Class
JDBC, SQLData
Attribute 1
….
Attribute N
Constructor(con,p1,...)
Methode F1(con,p1,..)
Methode P2(con,p1,…)
Java DB-Mapping 2/2
2. Package-Mapping
Class Record 1
PL/SQL-Package
Cursor 1 of Record 1
….
Cursor N of Record N
Java-Class
JDBC
OUT_F1
OUT_P2
Parameter 1
Parameter 1
Parameter N
Parameter N
Attribute 1
….
Attribute N
Class Record N
Function F1(p1,..)
Procedure P2(p1,…)
Constructor(con)
Methode F1(con,p1,..)
Methode P2(con,p1,…)
Attribute 1
….
Attribute N
Gewünschte Nachbesserung von
Architekturnachteilen
•
Object-Typen unterstützen nicht ROWID, %TYPE und INDEX BY TABLE
•
ein Type kann nicht Container von eigenen Instanzen referenzieren
•
ein SUPER –Attribut fehlt
•
die entsprechendes Gegenstück der z.B. in Java existierenden Interfaces
fehlt (deswegen beinhaltet TYPE_OBJECT das überflüssige Attribute
OBJECT_TYPE_NAME)
•
ein Type, der von einem anderen Type vererbt ist, oder von einem
Container referenziert wird, kann mittels REPLACE nicht mehr ersetzt
werden (DROP TYPE FORCE und anschließende Grants)
Q&A
• Objektorientierte PL/SQL-Programmierung, Andriy Terletskyy,
Michael Meyer, DOAG News Q3/2004, s.31-35
• Objektorientierte PL/SQL-Programmierung, Andriy Terletskyy,
17.
Deutsche ORACLE- Anwenderkonferenz 10./11. November 2004, CCM
Congress Center Mannheim; s.207-215
• Alternative zu J2EE Enterprise- Applicationen mit wenig Ballast,
Manfred Emmelmnn, Stephan Koop, Jürgen Hoffmann, Tim Lechler,
Carsten Paschilke, Andriy Terletskyy, Javamagazin 01/2005, s.49-59
Herunterladen