Skip to content

10. Oracle Express 11g Release 2

Wir befassen uns nun mit der Portierung der mit MySQL5 durchgeführten Arbeiten auf Oracle Express 11g Release 2.

10.1. Einrichtung der Arbeitsumgebung

10.1.1. Eclipse-Umgebung

Wir werden mit der folgenden Eclipse-Umgebung arbeiten:

  

Die oben genannten Oracle-Projekte befinden sich im Ordner [<exemples>/spring-database-config\oracle\eclipse].

Hinweis: Führen Sie den Befehl „[Alt-F5]“ aus, um alle Maven-Projekte neu zu generieren.

Starten Sie Oracle Express und dessen Client [OraManager] (siehe Abschnitt 23.6). Wir werden Folgendes erstellen:

  • die Datenbank [dbproduits] mit dem Projekt [generic-create-dbproduits];
  • die Datenbank [dbproduitscategories] mit dem Projekt [generic-create-dbproduitscategories];

10.1.2. Anlegen von Benutzern

Alles läuft nun in [OraManager] ab. Das Oracle-Projekt SGBD muss gestartet werden. Für den Systemadministrator werden die Anmeldedaten „system / system“ verwendet (dies muss zuvor konfiguriert worden sein). Wir werden zwei Benutzer anlegen:

  • [DBPRODUITS / dbproduits], der Eigentümer der Datenbank [dbproduits] sein wird;
  • [DBPRODUITSCATEGORIES / dbproduitscategories], der Eigentümer der Datenbank [dbproduits] sein wird;
  • in [6-7] lauten die Kennungen [system / system];
  • in [14]: dbproduits eingeben;
  • Bei [16] wurde der Benutzer zwar angelegt, verfügt jedoch nicht über ausreichende Rechte, um sich anzumelden. Diese werden ihm mithilfe eines Skripts SQL [17-18] erteilt;
  • in [19], den Benutzernamen in Großbuchstaben schreiben;

Wir wiederholen denselben Vorgang, um den Benutzer [DBPRODUITSCATEGORIES / dbproduitscategories] anzulegen:

  

10.1.3. Installation des Oracle-Treibers JDBC im Maven-Repository

Der Oracle-Treiber JDBC ist in den zentralen Maven-Repositorys nicht verfügbar. Er muss von Oracle heruntergeladen werden: [http://www.oracle.com/technetwork/apps-tech/jdbc-112010-090769.html]:

Nach dem Herunterladen muss er im lokalen Maven-Repository installiert werden. Dies geschieht mit dem folgenden Skript:

"%M2_HOME%\bin\mvn.bat" install:install-file -Dfile=ojdbc6.jar -Dpackaging=jar -DgroupId=com.oracle.jdbc -DartifactId=ojdbc6 -Dversion=1.0

wobei [%M2_HOME%] durch den Pfad zum Maven-Installationsverzeichnis ersetzt wird (siehe Abschnitt 23.2). Anschließend kann der Treiber JDBC über folgende Konfiguration in Maven-Projekte importiert werden:


        <dependency>
            <groupId>com.oracle.jdbc</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>1.0</version>
</dependency>

10.1.4. Erstellung der Datenbank [dbproduits]

Da wir nun über einen Benutzer [DBPRODUITS / dbproduits] verfügen, werden wir uns mit diesen Anmeldedaten bei Oracle anmelden:

  • in [6] muss dbproduits stehen;
  • in [9] die Datenbank [DBPRODUITS], die wir nutzen werden;

In der Klasse [ConfigJdbc] des Projekts [oracle-config-jdbc] werden folgende Verbindungsparameter verwendet:


    public final static String DRIVER_CLASSNAME = "oracle.jdbc.OracleDriver";
    public final static String URL_DBPRODUITS = "jdbc:oracle:thin:@localhost:1521:xe";
    public final static String USER_DBPRODUITS = "DBPRODUITS";
    public final static String PASSWD_DBPRODUITS = "dbproduits";
    public final static String URL_DBPRODUITSCATEGORIES = "jdbc:oracle:thin:@localhost:1521:xe";
    public final static String USER_DBPRODUITSCATEGORIES = "DBPRODUITSCATEGORIES";
public final static String PASSWD_DBPRODUITSCATEGORIES = "dbproduitscategories";

Sie müssen diese an Ihre Oracle-Konfiguration anpassen.

Im Projekt [oracle-config-jpa-eclipselink] ist die Entität JPA wie folgt definiert:

  

package generic.jpa.entities.dbproduits;

import generic.jdbc.config.ConfigJdbc;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity(name="Produit1")
@Table(name = ConfigJdbc.TAB_PRODUITS)
public class Produit {

    // Felder
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="genSeqProduits")
  @SequenceGenerator(name="genSeqProduits",sequenceName="PRODUITS_SEQUENCE", allocationSize=5)
    @Column(name = ConfigJdbc.TAB_PRODUITS_ID)
    private Long id;
    @Column(name = ConfigJdbc.TAB_PRODUITS_NOM, unique = true, length = 30, nullable = false)
    private String nom;
    @Column(name = ConfigJdbc.TAB_PRODUITS_CATEGORIE, nullable = false)
    private int categorie;
    @Column(name = ConfigJdbc.TAB_PRODUITS_PRIX, nullable = false)
    private double prix;
    @Column(name = ConfigJdbc.TAB_PRODUITS_DESCRIPTION, length = 100, nullable = false)
    private String description;

...
}
  • Zeilen 18–19: Die Strategie zur Generierung des Primärschlüssels der Tabelle [PRODUITS] lautet [strategy=GenerationType.SEQUENCE]. Für MySQL wurde die Strategie [@GeneratedValue(strategy = GenerationType.IDENTITY)] verwendet. Mit Oracle Express 11g ist diese Strategie nicht mehr verwendbar;
  • Zeile 18: Hier wird angegeben, dass der Primärschlüssel über einen Zahlengenerator ermittelt wird, der oft als Sequenz bezeichnet wird;
  • Zeile 19: Der Sequenzgenerator (das Attribut name verweist auf den Generator aus Zeile 18) erstellt eine Sequenz namens [PRODUITS_SEQUENCE] in der Datenbank [dbproduits]. Da Portabilität zwischen den Implementierungen von JPA gewünscht ist, ist es wichtig, der Sequenz einen Namen zu geben. Andernfalls würden die drei Implementierungen JPA ohne Zeile 19 Sequenzen erstellen, die nicht denselben Namen haben, was es JPA2 unmöglich machen würde, eine von JPA1 erstellte Datenbank zu nutzen;

Wir sind bereit, die Konfiguration [generic-create-dbproduits-eclipselink] auszuführen:

Durch die Ausführung dieser Konfiguration werden zwei Objekte erstellt:

  • eine Tabelle [PRODUITS];
  • eine Sequenz mit dem Namen [PRODUITS_SEQUENCE]

Die DDL der Tabelle [PRODUITS] lautet wie folgt:

 

Der Primärschlüssel [ID] wird nicht automatisch inkrementiert, wie es bei MySQL der Fall war. Das Projekt [spring-jdbc-03] geht jedoch davon aus, dass SGBD für die Generierung der Primärschlüssel der Tabelle [PRODUITS] zuständig ist. Wir werden ein Projekt trigger oder déclencheur anlegen. Ein Trigger ist eine im Projekt SGBD gespeicherte Prozedur, die unter bestimmten Bedingungen ausgeführt wird. Wir werden einen Trigger erstellen, der bei jedem neuen Einfügevorgang den Primärschlüssel des eingefügten Produkts anhand der Sequenz [PRODUITS_SEQUENCE] generiert, die durch die Konfiguration JPA erstellt wurde.

  • in [6] wird der Trigger [PRODUITS_ID_TRIGGER] [4] vor jedem Einfügen ausgeführt;
  • in [7] eine für SGBD spezifische gespeicherte Prozedur in Oracle. Sie gibt an, dass das Feld [ID] der Zeile, die eingefügt werden soll, mit dem folgenden Wert des Generators namens [PRODUITS_SEQUENCE] initialisiert werden muss;
 

Die Datenbank [dbproduits] ist nun bereit. Führen Sie die folgenden Konfigurationen durch:

  • [spring-jdbc-generic-01.IntroJdbc01];
  • [spring-jdbc-generic-01.IntroJdbc02];
  • [spring-jdbc-generic-03.JUnitTestDao1];
  • [spring-jdbc-generic-03.JUnitTestDao2];

Sie müssen alle erfolgreich abgeschlossen werden.

10.1.5. Erstellung der Datenbank [dbproduitscategories]

  

Wir führen nun das Projekt [generic-create-dbproduitscategories] aus, das die Datenbank [dbproduitscategories] generieren wird. Zuvor melden wir uns in [OraManager] mit den Anmeldedaten von [DBPRODUITSCATEGORIES / dbproduitscategories] an, um die an der Datenbank [dbproduitscategories] vorgenommenen Änderungen einsehen zu können:

  

Die verwendeten Entitäten JPA verfügen über folgende Strategien zur Generierung von Primärschlüsseln:

[Categorie]


public class Categorie implements AbstractCoreEntity {

    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="genSeqCategories")
  @SequenceGenerator(name="genSeqCategories",sequenceName="CATEGORIES_SEQUENCE", allocationSize=5)
    @Column(name = ConfigJdbc.TAB_JPA_ID)
    protected Long id;

[Produit]


public class Produit implements AbstractCoreEntity {
    // Eigenschaften
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="genSeqProduits2")
  @SequenceGenerator(name="genSeqProduits2",sequenceName="PRODUITS_SEQUENCE", allocationSize=5)
    @Column(name = ConfigJdbc.TAB_JPA_ID)
    protected Long id;

[Role]


public class Role implements AbstractCoreEntity {
    // Eigenschaften
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="genSeqRoles")
  @SequenceGenerator(name="genSeqRoles",sequenceName="ROLES_SEQUENCE", allocationSize=5)
    @Column(name = ConfigJdbc.TAB_JPA_ID)
    protected Long id;

[User]


public class User implements AbstractCoreEntity {
    // Eigenschaften
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="genSeqUsers")
  @SequenceGenerator(name="genSeqUsers",sequenceName="USERS_SEQUENCE", allocationSize=5)
    @Column(name = ConfigJdbc.TAB_JPA_ID)
    protected Long id;

[UserRole]


public class UserRole implements AbstractCoreEntity {
    // Eigenschaften
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="genSeqUsersRoles")
  @SequenceGenerator(name="genSeqUsersRoles",sequenceName="USERS_ROLES_SEQUENCE", allocationSize=5)
    @Column(name = ConfigJdbc.TAB_JPA_ID)
    protected Long id;

Wie bereits bei der Datenbank [dbproduits] werden fünf Sequenzen generiert. Diese werden von den Implementierungen JPA zur Generierung der Primärschlüssel verwendet. Die Implementierungen JPA verwenden keine Trigger, wie wir es zuvor getan haben, sondern fragen die Sequenzen ab, um den nächsten Primärschlüssel zu erhalten. Wir werden die Primärschlüssel ebenfalls mit Triggern generieren. Diese sind für das Projekt [spring-jdbc-04] erforderlich.

Wir führen die Konfiguration [generic-create-dbproduitscategories-eclipselink] aus:

und erhalten das folgende Ergebnis:

  

Anschließend generieren wir fünf Trigger, um die Primärschlüssel der fünf Tabellen zu generieren:

 

Die Trigger werden den Tabellen wie folgt zugeordnet:

Table
Trigger
Séquence
CATEGORIES
CATEGORIES_ID_TRIGGER
CATEGORIES_SEQUENCE
PRODUITS
PRODUITS_ID_TRIGGER
PRODUITS_SEQUENCE
ROLES
ROLES_ID_TRIGGER
ROLES_SEQUENCE
USERS
USERS_ID_TRIGGER
USERS_SEQUENCE
USERS_ROLES
USERS_ROLES_ID_TRIGGER
USERS_ROLES_SEQUENCE
  

Das Projekt [spring-jdbc-04] erfordert, dass die Spalte [VERSIONING] in jeder der folgenden Tabellen einen Standardwert hat:

Dies wird für alle fünf Tabellen durchgeführt.

Führen Sie nun die Konfigurationen aus:

  • [spring-jdbc-generic-04.JUnitTestDao];
  • [spring-jpa-generic-JUnitTestDao-hibernate-eclipselink] ;

Beide müssen erfolgreich sein.

10.2. Konfiguration der Ebene JDBC

 

Das Projekt [oracle-config-jdbc] konfiguriert die Schicht [JDBC] der folgenden Testarchitektur:

Das Projekt entspricht dem Konfigurationsprojekt [mysql-config-jdbc] der Schicht JDBC des SGBD MySQL (siehe Abschnitt 3.3). Wir stellen hier nur die Änderungen vor:

Die Datei [pom.xml] importiert den Oracle-Treiber JDBC:


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>dvp.spring.database</groupId>
    <artifactId>generic-config-jdbc</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>configuration generic jdbc</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.3.RELEASE</version>
    </parent>

    <dependencies>
        <!-- Variable Abhängigkeiten ********************************************** -->
        <!-- Treiber JDBC für SGBD -->
        <dependency>
            <groupId>com.oracle.jdbc</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>1.0</version>
        </dependency>
        <!-- Konstante Abhängigkeiten ********************************************** -->
        ....
    </dependencies>
...
</project>
  • Zeilen 18–22: Der Oracle-Treiber JDBC ersetzt den Treiber MySQL;

Die zweite Änderung befindet sich in der Klasse [ConfigJdbc], die die Zugangs-IDs für die Datenbanken definiert:


    // Verbindungsparameter
    public final static String DRIVER_CLASSNAME = "oracle.jdbc.OracleDriver";
    public final static String URL_DBPRODUITS = "jdbc:oracle:thin:@localhost:1521:xe";
    public final static String USER_DBPRODUITS = "DBPRODUITS";
    public final static String PASSWD_DBPRODUITS = "dbproduits";
    public final static String URL_DBPRODUITSCATEGORIES = "jdbc:oracle:thin:@localhost:1521:xe";
    public final static String USER_DBPRODUITSCATEGORIES = "DBPRODUITSCATEGORIES";
public final static String PASSWD_DBPRODUITSCATEGORIES = "dbproduitscategories";

Die dritte Änderung betrifft die maximale Anzahl an Parametern, die ein unterstützen kann:


    // Maximale Anzahl von Parametern eines [PreparedStatement]
    public final static int MAX_PREPAREDSTATEMENT_PARAMETERS = 1000;

Der Test [JUnitTestPushTheLimits] generiert Aufträge SQL für 5000 Produkte, die wiederum [PreparedStatement] mit 5000 Parametern erzeugen. MySQL hatte diesen Wert unterstützt, Oracle jedoch nicht. Wir haben diesen Wert auf 1000 gesenkt, und nun funktioniert es.

 

Hinweis: Führen Sie [Alt-F5] aus, um alle Maven-Projekte neu zu generieren.

Das Projekt [oracle-config-jpa-eclipseLink] konfiguriert die Ebene [JPA] der Testarchitektur:

Das Projekt entspricht dem Konfigurationsprojekt [mysql-config-jpa-eclipselink] (siehe Abschnitt 7.3) der Eclipselink-Schicht JPA des SGBD MySQL. Wir stellen hier nur die Änderungen vor:

Die erste befindet sich in der Klasse [ConfigJpa] in der Definition des Beans [jpaVendorAdapter]:


    // der Provider JPA
    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        // Hinweis: Die Entitäten JPA und die Eclipselink-Konfiguration befinden sich in der Datei META-INF/persistence.xml
        EclipseLinkJpaVendorAdapter eclipseLinkJpaVendorAdapter = new EclipseLinkJpaVendorAdapter();
        eclipseLinkJpaVendorAdapter.setShowSql(false);
        eclipseLinkJpaVendorAdapter.setDatabase(Database.ORACLE);
        eclipseLinkJpaVendorAdapter.setGenerateDdl(true);
        return eclipseLinkJpaVendorAdapter;
}
  • Zeile 7: Der Implementierung JPA wird mitgeteilt, dass sie mit einer Oracle-Datenbank arbeiten wird. Die Implementierung JPA übernimmt daraufhin sowohl die proprietären Datentypen als auch den proprietären Oracle-Schlüssel SQL.

Die zweite Änderung betrifft die Strategie zur Generierung von Primärschlüsseln. Die neue Strategie wurde in Abschnitt 10.1 vorgestellt.

10.4. Konfiguration der Hibernate-Schicht JPA

 

Hinweis: Führen Sie den Befehl „[Alt-F5]“ aus, um alle Maven-Projekte neu zu generieren.

Das Projekt [oracle-config-jpa-hibernate] entspricht dem Projekt [mysql-config-jpa-hibernate] (Abschnitt 6.3) und weist dieselben Änderungen auf, die bei der Portierung von [mysql-config-jpa-eclipselink] auf das Projekt [oracle-config-jpa-eclipselink] vorgenommen wurden (Absatz 10.3) vorgenommen wurden.

Nach Durchführung dieser Änderungen sollte die Ausführung der Konfiguration [spring-jpa-generic-JUnitTestDao-hibernate-eclipselink] erfolgreich sein.

10.5. Konfiguration der Schicht JPA OpenJpa

 

Hinweis: Führen Sie [Alt-F5] aus, um alle Maven-Projekte neu zu generieren.

Das Projekt [oracle-config-jpa-openjpa] entspricht dem Projekt [mysql-config-jpa-openjpa] (Abschnitt 8.3) und weist dieselben Änderungen auf, die bei der Portierung von [mysql-config-jpa-eclipselink] auf das Projekt [oracle-config-jpa-eclipselink] vorgenommen wurden (Absatz 10.3) vorgenommen wurden.

Nach Durchführung dieser Änderungen sollte die Ausführung der Konfiguration [spring-jpa-generic-JUnitTestDao-openjpa] erfolgreich sein.