Skip to content

10. Oracle Express 11g release 2

We gaan nu verder met de port naar Oracle Express 11g release 2 van wat er met MySQL5 is gedaan.

10.1. Het opzetten van de werkomgeving

10.1.1. Eclipse-omgeving

We gaan werken met de volgende Eclipse-omgeving:

  

De bovenstaande Oracle-projecten zijn te vinden in de map [<exemples>/spring-database-config\oracle\eclipse].

Opmerking: voer [Alt-F5] uit om alle Maven-projecten opnieuw te genereren.

Start Oracle Express en de bijbehorende client [OraManager] (zie paragraaf 23.6). We gaan het volgende genereren:

  • de database [dbproduits] met het project [generic-create-dbproduits];
  • de database [dbproduitscategories] met het project [generic-create-dbproduitscategories];

10.1.2. Gebruikers aanmaken

Alles vindt nu plaats in [OraManager]. Het Oracle-project SGBD moet worden gestart. We gebruiken de inloggegevens system / system voor de systeembeheerder (dit moet vooraf zijn geconfigureerd). We gaan twee gebruikers aanmaken:

  • [DBPRODUITS / dbproduits], die eigenaar wordt van de database [dbproduits];
  • [DBPRODUITSCATEGORIES / dbproduitscategories], die eigenaar wordt van de database [dbproduits];
  • in [6-7] zijn de ID's [system / system];
  • in [14]: vervang door dbproduits;
  • bij [16] is de gebruiker aangemaakt, maar hij heeft onvoldoende rechten om in te loggen. We gaan hem deze rechten toekennen met behulp van een script SQL [17-18];
  • in [19], zet de gebruikersnaam in hoofdletters;

We doen hetzelfde om de gebruiker [DBPRODUITSCATEGORIES / dbproduitscategories] aan te maken:

  

10.1.3. Installatie van de Oracle-driver JDBC in de Maven-repository

De Oracle-driver JDBC is niet beschikbaar in de centrale Maven-repositories. Deze moet worden gedownload van Oracle [http://www.oracle.com/technetwork/apps-tech/jdbc-112010-090769.html]:

Na het downloaden moet het in de lokale Maven-repository worden geïnstalleerd. Dit gebeurt met het volgende script:

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

waarbij [%M2_HOME%] moet worden vervangen door het pad naar de installatiemap van Maven (zie paragraaf 23.2). Zodra dit is gebeurd, kan de driver JDBC in Maven-projecten worden geïmporteerd via de volgende configuratie:


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

10.1.4. Het genereren van de database [dbproduits]

Nu we een gebruiker [DBPRODUITS / dbproduits] hebben, gaan we met deze inloggegevens verbinding maken met Oracle:

  • in [6], voer dbproduits in;
  • in [9] de database [DBPRODUITS] die we gaan gebruiken;

In de klasse [ConfigJdbc] van het project [oracle-config-jdbc] worden de volgende verbindingsparameters gebruikt:


    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";

U moet deze aanpassen aan uw Oracle-configuratie.

In het project [oracle-config-jpa-eclipselink] is de entiteit JPA als volgt gedefinieerd:

  

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 {

    // velden
    @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;

...
}
  • regels 18-19: de strategie voor het genereren van de primaire sleutel van de tabel [PRODUITS] is [strategy=GenerationType.SEQUENCE]. Voor MySQL werd de strategie [@GeneratedValue(strategy = GenerationType.IDENTITY)] gebruikt. Met Oracle Express 11g is deze strategie niet bruikbaar;
  • regel 18: hier wordt aangegeven dat de primaire sleutel wordt gegenereerd via een getallengenerator, die vaak ‘sequenties’ wordt genoemd;
  • regel 19: de sequentiegenerator (het attribuut name verwijst naar de generator uit regel 18) zal een sequentie met de naam [PRODUITS_SEQUENCE] aanmaken in de database [dbproduits]. Omdat we overdraagbaarheid tussen de implementaties JPA willen, is het belangrijk om de reeks een naam te geven. Anders, als regel 19 ontbreekt, zullen de drie implementaties JPA reeksen aanmaken die niet dezelfde naam hebben, waardoor het voor JPA2 onmogelijk wordt om een database te gebruiken die door JPA1 is aangemaakt;

We zijn klaar om de configuratie [generic-create-dbproduits-eclipselink] uit te voeren:

Door deze configuratie uit te voeren, worden twee objecten aangemaakt:

  • een tabel [PRODUITS];
  • een sequentie met de naam [PRODUITS_SEQUENCE]

De DDL uit de tabel [PRODUITS] is als volgt:

 

De primaire sleutel [ID] wordt niet automatisch opgehoogd, zoals dat wel het geval was bij MySQL. Het project [spring-jdbc-03] gaat er echter van uit dat SGBD de primaire sleutels van de tabel [PRODUITS] genereert. We gaan een trigger of déclencheur aanmaken. Een trigger is een opgeslagen procedure binnen SGBD die onder bepaalde voorwaarden wordt uitgevoerd. We gaan een trigger aanmaken die bij elke nieuwe invoer de primaire sleutel van het ingevoerde product genereert op basis van de reeks [PRODUITS_SEQUENCE], die is aangemaakt door de configuratie JPA.

  • in [6] wordt de trigger [PRODUITS_ID_TRIGGER] [4] vóór elke invoeging uitgevoerd;
  • in [7], een opgeslagen procedure die specifiek is voor de Oracle-trigger SGBD. Hierin wordt aangegeven dat het veld [ID] van de regel die zal worden ingevoegd, moet worden geïnitialiseerd met de volgende waarde van de generator met de naam [PRODUITS_SEQUENCE];
 

De database [dbproduits] is nu klaar. Voer de volgende configuraties uit:

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

Ze moeten allemaal slagen.

10.1.5. Genereren van de database [dbproduitscategories]

  

We voeren nu het project [generic-create-dbproduitscategories] uit, dat de database [dbproduitscategories] zal genereren. Daarvoor loggen we in [OraManager] in met de inloggegevens van [DBPRODUITSCATEGORIES / dbproduitscategories], zodat we de wijzigingen in de database [dbproduitscategories] kunnen bekijken:

  

De gebruikte entiteiten JPA hebben de volgende strategieën voor het genereren van primaire sleutels:

[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 {
    // eigenschappen
    @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 {
    // eigenschappen
    @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 {
    // eigenschappen
    @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 {
    // eigenschappen
    @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;

Net zoals bij de database [dbproduits] zullen er vijf sequenties worden gegenereerd. Deze worden door de implementaties JPA gebruikt om de primaire sleutels te genereren. De implementaties JPA maken geen gebruik van triggers zoals we eerder hebben gedaan, maar raadplegen de sequenties om de volgende primaire sleutel te verkrijgen. Wij zullen de primaire sleutels eveneens met triggers genereren. Deze zijn nodig voor het project [spring-jdbc-04].

We voeren de configuratie [generic-create-dbproduitscategories-eclipselink] uit:

en we krijgen het volgende resultaat:

  

Vervolgens genereren we vijf triggers om de primaire sleutels van de vijf tabellen te genereren:

 

De triggers worden als volgt aan de tabellen gekoppeld:

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
  

Voor het project [spring-jdbc-04] moet de kolom [VERSIONING] in elk van de tabellen een standaardwaarde hebben:

Dit doen we voor alle vijf tabellen.

Voer nu de configuraties uit:

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

Ze moeten allebei slagen.

10.2. Configuratie van de laag JDBC

 

Het project [oracle-config-jdbc] configureert de laag [JDBC] van de volgende testarchitectuur:

Het project is vergelijkbaar met het configuratieproject [mysql-config-jdbc] van de laag JDBC van SGBD MySQL (zie paragraaf 3.3). We geven hier alleen de wijzigingen weer:

Het bestand [pom.xml] importeert de Oracle-driver 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>
        <!-- variabele afhankelijkheden ********************************************** -->
        <!-- stuurprogramma JDBC van SGBD -->
        <dependency>
            <groupId>com.oracle.jdbc</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>1.0</version>
        </dependency>
        <!-- constante afhankelijkheden ********************************************** -->
        ....
    </dependencies>
...
</project>
  • regels 18-22: de Oracle-driver JDBC vervangt die van MySQL;

De tweede wijziging bevindt zich in de klasse [ConfigJdbc], die de toegangsgegevens voor de databases definieert:


    // verbindingsparameters
    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";

De derde wijziging betreft het maximale aantal parameters dat een driver kan ondersteunen:


    // maximaal aantal parameters van een [PreparedStatement]
    public final static int MAX_PREPAREDSTATEMENT_PARAMETERS = 1000;

De test [JUnitTestPushTheLimits] genereert SQL-opdrachten voor 5000 producten, die op hun beurt [PreparedStatement]-opdrachten met 5000 parameters zullen genereren. MySQL ondersteunde deze waarde wel, maar Oracle niet. We hebben deze waarde verlaagd naar 1000 en nu werkt het.

 

Opmerking: voer [Alt-F5] uit om alle Maven-projecten opnieuw te genereren.

Het project [oracle-config-jpa-eclipseLink] configureert de laag [JPA] van de testarchitectuur:

Het project is vergelijkbaar met het configuratieproject [mysql-config-jpa-eclipselink] (zie paragraaf 7.3) van de Eclipselink-laag JPA van SGBD MySQL. We geven alleen de wijzigingen weer:

De eerste wijziging bevindt zich in de klasse [ConfigJpa], in de definitie van de bean [jpaVendorAdapter]:


    // de provider JPA
    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        // Opmerking: de entiteiten JPA en de configuratie van EclipseLink staan in het bestand META-INF/persistence.xml
        EclipseLinkJpaVendorAdapter eclipseLinkJpaVendorAdapter = new EclipseLinkJpaVendorAdapter();
        eclipseLinkJpaVendorAdapter.setShowSql(false);
        eclipseLinkJpaVendorAdapter.setDatabase(Database.ORACLE);
        eclipseLinkJpaVendorAdapter.setGenerateDdl(true);
        return eclipseLinkJpaVendorAdapter;
}
  • regel 7: de implementatie JPA wordt geïnformeerd dat deze met een Oracle-database gaat werken. De implementatie JPA zal dan zowel de eigen datatypes als de eigen SQL van Oracle overnemen.

De tweede wijziging betreft de strategie voor het genereren van primaire sleutels. De nieuwe strategie is beschreven in paragraaf 10.1.

10.4. Configuratie van de Hibernate-laag JPA

 

Opmerking: voer [Alt-F5] uit om alle Maven-projecten opnieuw te genereren.

Het project [oracle-config-jpa-hibernate] is vergelijkbaar met het project [mysql-config-jpa-hibernate] (paragraaf 6.3) en bevat dezelfde aanpassingen die zijn doorgevoerd bij de overzetting van [mysql-config-jpa-eclipselink] naar het project [oracle-config-jpa-eclipselink] (paragraaf 10.3).

Als deze wijzigingen zijn doorgevoerd, zou de uitvoering van de configuratie [spring-jpa-generic-JUnitTestDao-hibernate-eclipselink] moeten slagen.

10.5. Configuratie van de laag JPA OpenJpa

 

Opmerking: voer [Alt-F5] uit om alle Maven-projecten opnieuw te genereren.

Het project [oracle-config-jpa-openjpa] is vergelijkbaar met het project [mysql-config-jpa-openjpa] (paragraaf 8.3) en bevat dezelfde aanpassingen die zijn doorgevoerd bij de overzetting van [mysql-config-jpa-eclipselink] naar het project [oracle-config-jpa-eclipselink] (paragraaf 10.3).

Als deze wijzigingen zijn doorgevoerd, zou de uitvoering van de configuratie [spring-jpa-generic-JUnitTestDao-openjpa] moeten slagen.