Skip to content

10. Oracle Express 11g Release 2

Wir werden nun die Portierung der mit MySQL 5 durchgeführten Maßnahmen auf Oracle Express 11g Release 2 erörtern.

10.1. Einrichten der Entwicklungsumgebung

10.1.1. Eclipse-Umgebung

Wir werden mit der folgenden Eclipse-Umgebung arbeiten:

  

Die oben aufgeführten Oracle-Projekte befinden sich im Ordner [<examples>/spring-database-config\oracle\eclipse].

Hinweis: Drücken Sie [Alt-F5], um alle Maven-Projekte neu zu generieren.

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

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

10.1.2. Benutzer anlegen

Alles findet nun in [OraManager] statt. Das Oracle-DBMS muss laufen. Wir verwenden die Anmeldedaten system / system für den Systemadministrator (dies muss zuvor konfiguriert worden sein). Wir erstellen zwei Benutzer:

  • [DBPRODUITS / dbproduits], der Eigentümer der Datenbank [dbproduits] sein wird;
  • [DBPRODUCTSCATEGORIES / dbproducts-categories], der Eigentümer der Datenbank [dbproducts-categories] sein wird;
  • In [6-7] lauten die Anmeldedaten [system / system];
  • in [14]: enter dbproduits;
  • in [16] wurde der Benutzer angelegt, verfügt jedoch nicht über ausreichende Berechtigungen, um sich anzumelden. Wir werden ihm diese mithilfe eines SQL-Skripts [17-18] erteilen;
  • in [19] geben Sie den Benutzernamen in Großbuchstaben ein;

Wir gehen genauso vor, um den Benutzer [DBPRODUITSCATEGORIES / dbproduitscategories] anzulegen:

  

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

Der Oracle JDBC-Treiber 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 mithilfe des folgenden DOS-Skripts [install.bat] [2]:

"%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 werden sollte (siehe Abschnitt 23.2). Sobald dies erledigt ist, kann der JDBC-Treiber mit der folgenden Konfiguration in Maven-Projekte importiert werden:


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

10.1.4. Erstellen der Datenbank [dbproduits]

Da wir nun über einen Benutzer [DBPRODUITS / dbproduits] verfügen, stellen wir mit diesen Anmeldedaten eine Verbindung zu Oracle her:

  • Geben Sie in [6] „dbproduits“ ein;
  • in [9] die Datenbank [DBPRODUITS], die wir verwenden werden;

In der Klasse [ConfigJdbc] des Projekts [oracle-config-jdbc] lauten die verwendeten Verbindungsparameter wie folgt:


    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 JPA-Entität 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 {
 
    // fields
    @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 haben wir die Strategie [ ] [@GeneratedValue(strategy = GenerationType.IDENTITY)] verwendet. Bei Oracle Express 11g kann diese Strategie nicht verwendet werden;
  • Zeile 18: Wir legen fest, dass der Primärschlüssel mithilfe eines Zahlengenerators, oft als Sequenz bezeichnet, generiert 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 wir Portabilität zwischen JPA-Implementierungen anstreben, ist es wichtig, die Sequenz zu benennen. Andernfalls, ohne Zeile 19, würden die drei JPA-Implementierungen Sequenzen mit unterschiedlichen Namen erstellen, was es JPA2 unmöglich machen würde, eine von JPA1 erstellte Datenbank zu verwenden;

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

Durch das Ausführen dieser Konfiguration werden zwei Objekte erstellt:

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

Die DDL für die Tabelle [PRODUCTS] lautet wie folgt:

 

Der Primärschlüssel [ID] wird nicht wie bei MySQL automatisch inkrementiert. Das Projekt [spring-jdbc-03] geht jedoch davon aus, dass das DBMS die Generierung von Primärschlüsseln für die Tabelle [PRODUCTS] übernimmt. Wir werden einen Trigger erstellen. Ein Trigger ist eine gespeicherte Prozedur innerhalb des DBMS, die unter bestimmten Bedingungen ausgeführt wird. Wir werden einen Trigger erstellen, der bei jedem neuen Einfügen den Primärschlüssel des eingefügten Produkts auf der Grundlage der durch die JPA-Konfiguration erstellten Sequenz [PRODUCTS_SEQUENCE] generiert.

  • In [6] wird vor jedem Einfügen der Trigger [PRODUCTS_ID_TRIGGER] [4] ausgeführt;
  • in [7] eine für das Oracle-DBMS spezifische gespeicherte Prozedur. Sie legt fest, dass das Feld [ID] der einzufügenden Zeile mit dem nächsten Wert aus dem Generator namens [PRODUITS_SEQUENCE] initialisiert werden muss;
 

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

  • [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 sein.

10.1.5. Erstellen der Datenbank [dbproduitscategories]

  

Wir führen nun das Projekt [generic-create-dbproduitscategories] aus, wodurch die Datenbank [dbproduitscategories] erstellt wird. Zuvor stellen wir in [OraManager] eine Verbindung mit den Anmeldedaten [DBPRODUITSCATEGORIES / dbproduitscategories] her, damit wir die an der Datenbank [dbproduitscategories] vorgenommenen Änderungen beobachten können:

  

Die verwendeten JPA-Entitäten verfügen über die folgenden Strategien zur Primärschlüsselgenerierung:

[Kategorie]


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;

[Produkt]


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

[Rolle]


public class Role implements AbstractCoreEntity {
    // properties
    @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 {
    // properties
    @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 {
    // properties
    @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 für die Datenbank [dbproduits] werden fünf Sequenzen generiert. Diese werden von JPA-Implementierungen zur Generierung von Primärschlüsseln verwendet. JPA-Implementierungen verwenden keine Trigger wie zuvor, sondern fragen die Sequenzen ab, um den nächsten Primärschlüssel zu erhalten. Wir werden die Primärschlüssel ebenfalls mithilfe von 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 erstellen wir fünf Trigger, um die Primärschlüssel für die fünf Tabellen zu generieren:

 

Die Trigger sind wie folgt mit den Tabellen verknüpft:

Tabelle
Trigger
Sequenz
KATEGORIEN
KATEGORIEN_ID_AUSLÖSER
KATEGORIEN_SEQUENZ
PRODUKTE
PRODUKTE_ID_TRIGGER
PRODUKTE_SEQUENZ
ROLLEN
ROLLEN_ID_TRIGGER
ROLLEN_SEQUENZ
BENUTZER
BENUTZER_ID_TRIGGER
BENUTZER_SEQUENZ
USERS_ROLES
BENUTZER_ROLLEN_ID_TRIGGER
BENUTZER_ROLLEN_SEQUENZ
  

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

Wir tun dies für alle fünf Tabellen.

Führen Sie nun die Konfigurationen aus:

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

Beide sollten erfolgreich sein.

10.2. Konfigurieren der JDBC-Schicht

 

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

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

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


<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>
        <!-- dépendances variables ********************************************** -->
        <!-- driver JDBC from SGBD -->
        <dependency>
            <groupId>com.oracle.jdbc</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>1.0</version>
        </dependency>
        <!-- dépendances constantes ********************************************** -->
        ....
    </dependencies>
...
</project>
  • Zeilen 18–22: Der Oracle-JDBC-Treiber ersetzt den MySQL-Treiber;

Die zweite Änderung betrifft die Klasse [ConfigJdbc], die die Datenbank-Anmeldedaten definiert:


    // paramètres de connexion
    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 von Parametern, die ein unterstützen kann:


    // max number of parameters of a [PreparedStatement]
    public final static int MAX_PREPAREDSTATEMENT_PARAMETERS = 1000;

Der Test [JUnitTestPushTheLimits] generiert SQL-Anweisungen für 5.000 Produkte, wodurch [PreparedStatement]-Objekte mit 5.000 Parametern erzeugt werden. MySQL unterstützte diesen Wert, Oracle jedoch nicht. Wir haben diesen Wert auf 1.000 gesenkt, und nun funktioniert es.

 

Hinweis: Drücken Sie [Alt-F5], um alle Maven-Projekte neu zu generieren.

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

Das Projekt ähnelt dem Konfigurationsprojekt [mysql-config-jpa-eclipselink] (siehe Abschnitt 7.3) für die EclipseLink-JPA-Schicht des MySQL-DBMS. Wir stellen hier nur die Änderungen vor:

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


    // the provider JPA
    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        // Note: JPA entities and Eclipselink configuration are in the META-INF/persistence.xml file
        EclipseLinkJpaVendorAdapter eclipseLinkJpaVendorAdapter = new EclipseLinkJpaVendorAdapter();
        eclipseLinkJpaVendorAdapter.setShowSql(false);
        eclipseLinkJpaVendorAdapter.setDatabase(Database.ORACLE);
        eclipseLinkJpaVendorAdapter.setGenerateDdl(true);
        return eclipseLinkJpaVendorAdapter;
}
  • Zeile 7: Wir teilen der JPA-Implementierung mit, dass sie mit einer Oracle-Datenbank arbeiten wird. Die JPA-Implementierung übernimmt dann die proprietären Datentypen und die SQL von Oracle.

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

10.4. Konfigurieren der Hibernate-JPA-Schicht

 

Hinweis: Drücken Sie [Alt-F5], 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] (Abschnitt 10.3) zugrunde lagen.

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

10.5. Konfiguration der OpenJpa-JPA-Schicht

 

Hinweis: Drücken Sie [Alt-F5], um alle Maven-Projekte neu zu generieren.

Das Projekt [oracle-config-jpa-openjpa] ähnelt dem Projekt [mysql-config-jpa-openjpa] (Abschnitt 8.3) und weist dieselben Änderungen auf, die zur Portierung des Projekts [mysql-config-jpa-eclipselink] auf das Projekt [oracle-config-jpa-eclipselink] (Abschnitt 10.3) verwendet wurden.

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