Einleitung
In datengetriebenen Anwendungen ist eine sauber strukturierte Geschäftslogik entscheidend für eine skalierbare, wartbare und performante Architektur.
Dieser Artikel beschreibt eine konkrete Architektur für die Implementierung von Geschäftslogik in PL/SQL, die sowohl wiederverwendbar als auch analysierbar bleibt und sich effizient von verschiedenen Anwendungen nutzen lässt.
Wichtige Abgrenzung:
- Diese Struktur dient ausschließlich der Implementierung der Geschäftslogik, nicht der Abbildung der Anwendungslogik oder der Darstellung in einem Frontend wie Oracle APEX.
- Die Architektur ist so gestaltet, dass verschiedene Konsumenten (APIs, Batch-Prozesse, Microservices) die Geschäftslogik einheitlich wiederverwenden können.
- Analyse und Wartung werden erleichtert, indem die Geschäftslogik durch eine klare Trennung von Verantwortlichkeiten strukturiert wird.
Ziele dieser Architektur
✅ Zentrale Geschäftslogik für viele Konsumenten bereitstellen
✅ Klare Trennung zwischen Datenzugriff, Geschäftslogik und Schnittstellen
✅ Einfache Wartung und Analyse durch definierte Abhängigkeitsregeln
✅ Minimierung von Code-Duplizierung und Fehleranfälligkeit
1. Kernprinzipien der Package-Architektur
1.1 Trennung von Datenzugriff und Geschäftslogik
Die Architektur stellt sicher, dass:
- Nur
_TAPIund_REPO-Packages DML-Operationen (INSERT, UPDATE, DELETE) ausführen dürfen. - Service (
_SERVICES) und API (_API) Packages keine direkte DML-Operationen enthalten dürfen, sondern stattdessen auf_TAPIoder_REPOzugreifen müssen. - Die Geschäftslogik in
_SERVICESzentralisiert ist, während_APIals Fassade für externe Konsumenten fungiert.
Warum ist das wichtig?
- Verhindert unkontrollierte Änderungen an Daten und sorgt für konsistente Geschäftsregeln.
- Steigert die Wiederverwendbarkeit – dieselben Geschäftsregeln können von verschiedenen Anwendungen genutzt werden.
- Vereinfacht Tests und Debugging, da sich Datenbankzugriffe klar von der Geschäftslogik trennen lassen.
2. Strukturierung der Package-Typen und Abhängigkeitsregeln
Die folgende Tabelle zeigt, welche Package-Typen welche anderen Typen referenzieren dürfen:
| Package-Typ | Suffix | Zuständig für | DML erlaubt? | Darf referenzieren |
|---|---|---|---|---|
| Table-API-Package | _TAPI | CRUD-Operationen auf einer Tabelle | ✅ Ja | _DEFS |
| Repository-Package | _REPO | Optimierte Datenzugriffe, komplexe Abfragen, Performancetuning | ✅ Ja | _DEFS, _CONSTANTS |
| Definitions-Package | _DEFS | Enthält Subtypen zu einem bestimmten Kontext | ❌ Nein | _DEFS, _API (aus anderem Schema) |
| Konstanten-Package | _CONSTANTS | Globale Konstanten für das Schema | ❌ Nein | _DEFS, _API (aus anderem Schema) |
| Service-Package | _SERVICES | Zentrale Geschäftslogik | ❌ Nein | _TAPI, _REPO, _DEFS, _CONSTANTS, _SERVICES, _UTILS, _VALIDATIONS, _API (aus anderem Schema) |
| Utility-Package | _UTILS | Allgemeine Hilfsfunktionen (z. B. Datumskonvertierung, String-Operationen) | ❌ Nein | _DEFS, _CONSTANTS, _UTILS, _VALIDATIONS |
| Validierungs-Package | _VALIDATIONS | Validierungslogik für Eingaben und Geschäftsregeln | ❌ Nein | _DEFS, _CONSTANTS, _UTILS, _VALIDATIONS |
| API-Package | _API | Übersetzung eines fachlichen Use-Cases in technische Implementierung | ❌ Nein | _TAPI, _REPO, _DEFS, _CONSTANTS, _SERVICES, _UTILS, _VALIDATIONS, _API (aus anderem Schema) |
✅ Nur _TAPI und _REPO dürfen DML ausführen
❌ _SERVICES und _API müssen _TAPI oder _REPO verwenden, um DML auszuführen
3. Abhängigkeitsgraph der PL/SQL-Packages
(Hier kann der visualisierte Abhängigkeitsgraph angezeigt werden.)
4. Beispiele für verschiedene Package-Typen
4.1 Table-API-Package (_TAPI)
Ein automatisch generiertes CRUD-Interface, das für eine Tabelle die Standardmethoden bereitstellt.
sqlKopierenBearbeitenCREATE OR REPLACE PACKAGE employee_tapi AS
PROCEDURE insert_employee(p_emp employees%ROWTYPE);
PROCEDURE update_employee(p_emp employees%ROWTYPE);
PROCEDURE delete_employee(p_emp_id NUMBER);
END employee_tapi;
/
✅ DML erlaubt: INSERT, UPDATE, DELETE
4.2 Repository-Package (_REPO)
Erweitert die _TAPI, falls Performance-Probleme auftreten oder komplexe SQL-Abfragen benötigt werden.
sqlKopierenBearbeitenCREATE OR REPLACE PACKAGE customer_repo AS
FUNCTION get_customer_by_email(p_email VARCHAR2) RETURN SYS_REFCURSOR;
END customer_repo;
/
✅ DML erlaubt für komplexe Abfragen oder optimierte Zugriffe
4.3 Service-Package (_SERVICES)
Ein Service-Package enthält Geschäftslogik, führt aber selbst keine DML-Operationen aus!
sqlKopierenBearbeitenCREATE OR REPLACE PACKAGE order_services AS
FUNCTION calculate_total(p_order_id NUMBER) RETURN NUMBER;
PROCEDURE finalize_order(p_order_id NUMBER);
END order_services;
/
❌ DML-Verbot: Muss order_tapi.update_order_status aufrufen
4.4 API-Package (_API)
Ein API-Package gibt fachliche Use Cases nach außen frei, führt aber keine direkten DML-Operationen durch.
sqlKopierenBearbeitenCREATE OR REPLACE PACKAGE order_api AS
FUNCTION get_order_total(p_order_id NUMBER) RETURN NUMBER;
PROCEDURE process_order(p_order_id NUMBER);
END order_api;
/
❌ DML-Verbot: Muss order_services.finalize_order aufrufen
5. Fazit: Warum ist diese Architektur so vorteilhaft?
✅ Wiederverwendbarkeit:
- Dieselbe Geschäftslogik kann von verschiedenen Anwendungen (APIs, Batch-Prozesse, externe Systeme) genutzt werden.
✅ Skalierbarkeit:
- Saubere Trennung zwischen Datenzugriff, Geschäftslogik und API-Schicht erleichtert zukünftige Erweiterungen.
✅ Wartbarkeit & Analysefähigkeit:
- Änderungen an der Geschäftslogik sind einfacher durchzuführen, da sich alles an einem zentralen Ort befindet (
_SERVICES). - Reduzierung von Fehlerquellen, da DML-Operationen nur in
_TAPIund_REPOstattfinden dürfen.
Diese Struktur macht die PL/SQL-Geschäftslogik skalierbar, wartbar und robust, unabhängig davon, welche Anwendungen sie nutzen.
