Skip to content

13. SQL Server 2014

Wir wenden uns nun der Übertragung der mit MySQL durchgeführten Änderungen auf SQL Server 2014 zu.

13.1. Einrichtung der Arbeitsumgebung

13.1.1. Eclipse-Umgebung

Wir werden mit der folgenden Eclipse-Umgebung arbeiten:

  

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

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

13.1.2. Erstellung der Datenbanken

Wie bereits bei Oracle und DB2 müssen wir den Treiber JDBC des SQL-Servers im lokalen Maven-Repository installieren.

  

Die Datei [install.bat] enthält den folgenden Code:

"%M2_HOME%\bin\mvn.bat" install:install-file -Dfile=sqljdbc4-3.0.jar -Dpackaging=jar -DgroupId=com.microsoft.sqlserver -DartifactId=sqljdbc4 -Dversion=4.0

wobei [%M2-HOME%] das Maven-Installationsverzeichnis ist (siehe Abschnitt 23.2, Seite 466). Nach dieser Installation kann der Treiber JDBC des SQL-Servers in den Dateien [pom.xml] über die folgende Abhängigkeit referenziert werden:


        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>sqljdbc4</artifactId>
            <version>4.0</version>
</dependency>

Im weiteren Verlauf erfolgt die Verbindung zu den Datenbanken SQL und SERVER mit den Anmeldedaten [sa / msde]. Starten Sie den SQL-Server und dessen Client [MsManager] (siehe Abschnitt 23.9).

  • in [1], laden Sie das Skript SQL [<exemples>\spring-database-config\sqlserver\databases\dbproduits.sql];
  • in [2] war es nicht möglich, dieselbe Tabelle [PRODUITS] für die Projekte [spring-jdbc-01 à 03] zu verwenden. Der Grund dafür ist:
    • Die Projekte [spring-jdbc-01 et 02] fügen Zeilen mit ihren Primärschlüsseln ein;
    • das Projekt [spring-jdbc-03] fügt Zeilen ohne Primärschlüssel ein und erwartet, dass SGBD diese generiert. Dazu muss der Primärschlüssel von [ID] vom Typ [Identity] sein. Dieser Typ unterstützt jedoch im SQL-Server nur die automatische Generierung von Primärschlüsseln und erlaubt kein Einfügen einer Zeile mit einem vom Benutzer festgelegten Primärschlüssel. In diesem Fall wird ein Fehler gemeldet, den ich nicht umgehen konnte. Die Projekte [spring-jdbc-01 et 02] verwenden die Tabelle [PRODUITS] ohne automatische Generierung von Primärschlüsseln. Das Projekt [spring-jdbc-03] verwendet die Tabelle [PRODUITS2] mit automatischer Generierung von Primärschlüsseln.

Führen Sie nun 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.

Erstellen wir nun die Datenbank [dbproduitscategories]. Wiederholen Sie für [dbproduitscategories] den Vorgang, der zur Erstellung von [dbproduits] durchgeführt wurde. Das zu ladende Skript SQL befindet sich unter [<exemples>\spring-database-config\sqlserver\databases\ dbproduitscategories.sql];

  

Führen Sie nun die folgenden Konfigurationen aus:

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

Beide müssen erfolgreich sein.

13.2. Konfiguration der Schicht JDBC

 

Das Projekt [sqlserver-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 Treiber JDBC aus dem SQL-Server:


<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 des SGBD -->
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>sqljdbc4</artifactId>
            <version>4.0</version>
        </dependency>
        <!-- konstante Abhängigkeiten ********************************************** -->
        ...
    </dependencies>
...
</project>
  • Zeilen 18–22: den Treiber JDBC vom Server SQL;

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


    // Verbindungsparameter
    public final static String DRIVER_CLASSNAME = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
    public final static String URL_DBPRODUITS = "jdbc:sqlserver://localhost\\SQLEXPRESS:1433;databaseName=dbproduits";
    public final static String USER_DBPRODUITS = "sa";
    public final static String PASSWD_DBPRODUITS = "msde";
    public final static String URL_DBPRODUITSCATEGORIES = "jdbc:sqlserver://localhost\\SQLEXPRESS:1433;databaseName=dbproduitscategories";
    public final static String USER_DBPRODUITSCATEGORIES = "sa";
public final static String PASSWD_DBPRODUITSCATEGORIES = "msde";

Die dritte Änderung, die vorgenommen werden kann, betrifft die maximale Anzahl von Parametern, die ein [PreparedStatement] unterstützen kann:


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

Der Test [JUnitTestPushTheLimits] generiert Aufträge SQL für 5000 Produkte, die wiederum [PreparedStatement] mit 5000 Parametern erzeugen. MySQL hatte diesen Wert unterstützt. Der SQL-Server hat eine Fehlermeldung ausgegeben, wonach diese Grenze bei 2100 lag.

Die vierte Änderung betrifft die vom Projekt [spring-jdbc-03] verwendete Tabelle. Es handelt sich nicht mehr um [PRODUITS], sondern um [PRODUITS2]:


    // Aufträge SQL [jdbc-03]
    public final static String V2_INSERT_PRODUITS = "INSERT INTO PRODUITS2(NOM, CATEGORIE, PRIX, DESCRIPTION) VALUES (?, ?, ?, ?)";
    public final static String V2_DELETE_ALLPRODUITS = "DELETE FROM PRODUITS2";
    public final static String V2_DELETE_PRODUITS = "DELETE FROM PRODUITS2 WHERE ID=?";
    public final static String V2_SELECT_ALLPRODUITS = "SELECT ID, NOM, CATEGORIE, PRIX, DESCRIPTION FROM PRODUITS2";
    public final static String V2_SELECT_PRODUIT_BYID = "SELECT NOM, CATEGORIE, PRIX, DESCRIPTION FROM PRODUITS2 WHERE ID=?";
    public final static String V2_SELECT_PRODUIT_BYNAME = "SELECT ID, CATEGORIE, PRIX, DESCRIPTION FROM PRODUITS2 WHERE NOM=?";
public final static String V2_UPDATE_PRODUITS = "UPDATE PRODUITS2 SET NOM=?, PRIX=?, CATEGORIE=?, DESCRIPTION=? WHERE ID=?";

13.3. Konfiguration der Ebene JPA OpenJpa

 

Das Projekt [sqlserver-config-jpa-openjpa] konfiguriert die Schicht [JPA] der Testarchitektur:

Das Projekt entspricht dem Konfigurationsprojekt [mysql-config-jpa-openjpa] der Schicht JPA OpenJpa des SGBD MySQL (siehe Abschnitt 8.3). Tatsächlich verwenden beide SGBD die Annotation [@GeneratedValue(strategy = GenerationType.IDENTITY)] zur Generierung der Primärschlüssel. Es sind zwei Änderungen vorzunehmen. Diese befinden sich in der Definition des Beans [jpaVendorAdapter] der Klasse [ConfigJpa]:


    // der Provider JPA
    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        OpenJpaVendorAdapter openJpaVendorAdapter = new OpenJpaVendorAdapter();
        openJpaVendorAdapter.setShowSql(false);
        openJpaVendorAdapter.setDatabase(Database.SQL_SERVER);
        openJpaVendorAdapter.setGenerateDdl(true);
        return openJpaVendorAdapter;
}
  • Zeile 6: Der Implementierung JPA wird mitgeteilt, dass sie mit einer SQL-Server-Datenbank arbeiten wird. Die Implementierung JPA übernimmt dann sowohl die proprietären Datentypen als auch den Eigentümer SQL dieses SGBD.

Die zweite Änderung betrifft die Entitäten JPA, die mit den Tabellen [PRODUITS] und [PRODUITS2] verknüpft sind:

  

Die Entität [Produit] ist mit der Tabelle [PRODUITS] verknüpft, ohne dass Primärschlüssel automatisch generiert werden (keine Kennzeichnung [@GeneratedValue]):


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

// Felder
@Id
@Column(name = ConfigJdbc.TAB_PRODUITS_ID)
private Long id;

Die Entität [Produit2] ist mit der Tabelle [PRODUITS2] verknüpft, wobei Primärschlüssel automatisch generiert werden:


@Entity(name = "Produit2")
@Table(name = ConfigJdbc.TAB_PRODUITS2)
public class Produit2 {

// Felder
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = ConfigJdbc.TAB_PRODUITS_ID)
private Long id;

Außerdem muss das Projekt, das die Datenbank [dbproduits] generiert, so geändert werden, dass es angibt, dass sich nun zwei Entitäten JPA in der Datenbank befinden:

  

Die Datei [persistence.xml] ändert sich wie folgt:


<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="generic-jpa-entities-dbproduits" transaction-type="RESOURCE_LOCAL">
        <!-- Entitäten JPA -->
        <class>generic.jpa.entities.dbproduits.Produit</class>
        <class>generic.jpa.entities.dbproduits.Produit2</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
    </persistence-unit>
</persistence>

Das Projekt [generic-create-dbproduits] ist allen SGBD gemeinsam. Die Ebene JPA der zuvor untersuchten Projekte enthielt die Entität [Produit2] nicht. Man könnte sich daher fragen, ob die Referenzierung einer nicht vorhandenen Entität JPA das Projekt für diese SGBD zum Absturz bringen würde. Die Tests zeigen, dass dies nicht der Fall ist.

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

13.4. Konfiguration der Hibernate-Schicht JPA

 

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

Das Projekt [sqlserver-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-openjpa] auf das Projekt [sqlserver-config-jpa-openjpa] (Abschnitt 8.3) vorgenommen wurden.

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

 

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

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

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