Skip to content

13. SQL Server 2014

Ora discuteremo del porting di quanto fatto con MySQL su SQL Server 2014.

13.1. Configurazione dell'ambiente di lavoro

13.1.1. Ambiente Eclipse

Lavoreremo con il seguente ambiente Eclipse:

  

I progetti SQL Server sopra elencati si trovano nella cartella [<examples>/spring-database-config\sqlserver\eclipse].

Nota: premere [Alt-F5] per rigenerare tutti i progetti Maven.

13.1.2. Generazione dei database

Come abbiamo fatto con Oracle e DB2, dovremo installare il driver JDBC di SQL Server nel repository Maven locale.

  

Il file [install.bat] contiene il seguente codice:

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

dove [%M2-HOME%] è la directory di installazione di Maven (vedere la sezione 23.2, pagina 466). Dopo questa installazione, è possibile fare riferimento al driver JDBC di SQL Server nei file [pom.xml] utilizzando la seguente dipendenza:


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

Nel resto di questa guida, le connessioni ai database SQL Server vengono effettuate utilizzando le credenziali [sa / msde]. Avviare SQL Server e il suo client [MsManager] (vedere la sezione 23.9).

  • In [1], caricare lo script SQL [<examples>\spring-database-config\sqlserver\databases\dbproduits.sql];
  • in [2], non è stato possibile utilizzare la stessa tabella [PRODUCTS] per i progetti [da spring-jdbc-01 a 03]. Il motivo è che:
    • i progetti [spring-jdbc-01 e 02] inseriscono righe con le loro chiavi primarie;
    • il progetto [spring-jdbc-03] inserisce righe senza chiavi primarie e si aspetta che sia il DBMS a generarle. Affinché ciò funzioni, la chiave primaria [ID] deve essere di tipo [Identity]. Tuttavia, questo tipo in SQL Server supporta solo la generazione automatica di chiavi primarie e non consente l'inserimento di una riga con una chiave primaria definita dall'utente. Viene quindi segnalato un errore e non sono riuscito a risolverlo. I progetti [spring-jdbc-01 e 02] utilizzano la tabella [PRODUCTS] senza generazione automatica della chiave primaria. Il progetto [spring-jdbc-03] utilizza la tabella [PRODUCTS2] con generazione automatica della chiave primaria.

Ora, esegui le configurazioni:

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

Dovrebbero superare tutti i test.

Ora generiamo il database [dbproduitscategories]. Ripetiamo la procedura utilizzata per creare [dbproduits] per [dbproduitscategories]. Lo script SQL da caricare si trova in [<examples>\spring-database-config\sqlserver\databases\ dbproduitscategories.sql] ;

  

Ora, esegui le configurazioni:

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

Entrambe dovrebbero superare il test.

13.2. Configurazione del livello JDBC

 

Il progetto [sqlserver-config-jdbc] configura il livello [JDBC] della seguente architettura di test:

Il progetto è simile al progetto di configurazione [mysql-config-jdbc] per il livello JDBC del DBMS MySQL (vedere la Sezione 3.3). Presentiamo solo le modifiche:

Il file [pom.xml] importa il driver JDBC di 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>
        <!-- dépendances variables ********************************************** -->
        <!-- driver JDBC from SGBD -->
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>sqljdbc4</artifactId>
            <version>4.0</version>
        </dependency>
        <!-- dépendances constantes ********************************************** -->
        ...
    </dependencies>
...
</project>
  • righe 18-22: il driver JDBC di SQL Server;

La seconda modifica riguarda la classe [ConfigJdbc], che definisce le credenziali del database:


    // paramètres de connexion
    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";

La terza modifica che è possibile apportare riguarda il numero massimo di parametri che un [PreparedStatement] può supportare:


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

Il test [JUnitTestPushTheLimits] genera istruzioni SQL relative a 5.000 prodotti, il che comporta la creazione di oggetti [PreparedStatement] con 5.000 parametri. MySQL ha supportato questo valore. SQL Server ha restituito un errore indicando che tale limite era pari a 2.100.

La quarta modifica riguarda la tabella utilizzata dal progetto [spring-jdbc-03]. Non è più [PRODUCTS] ma [PRODUCTS2]:


    // ordres 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. Configurazione del livello JPA di OpenJPA

 

Il progetto [sqlserver-config-jpa-openjpa] configura il livello [JPA] dell'architettura di test:

Il progetto è analogo al progetto di configurazione [mysql-config-jpa-openjpa] per il livello JPA OpenJpa del DBMS MySQL (vedere la Sezione 8.3). Infatti, entrambi i DBMS utilizzano l'annotazione [@GeneratedValue(strategy = GenerationType.IDENTITY)] per generare le chiavi primarie. Ci sono due modifiche da apportare. Si trovano nella definizione del bean [jpaVendorAdapter] nella classe [ConfigJpa]:


    // the provider JPA
    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        OpenJpaVendorAdapter openJpaVendorAdapter = new OpenJpaVendorAdapter();
        openJpaVendorAdapter.setShowSql(false);
        openJpaVendorAdapter.setDatabase(Database.SQL_SERVER);
        openJpaVendorAdapter.setGenerateDdl(true);
        return openJpaVendorAdapter;
}
  • Riga 6: Indichiamo all'implementazione JPA che opererà con un database SQL Server. L'implementazione JPA adotterà quindi sia i tipi di dati proprietari che l'SQL proprietario di questo DBMS.

La seconda modifica riguarda le entità JPA associate alle tabelle [PRODUCTS] e [PRODUCTS2]:

  

L'entità [Product] è associata alla tabella [PRODUCTS] senza generazione automatica di chiavi primarie (nessuna annotazione [@GeneratedValue]):


@Entity(name = "Produit1")
@Table(name = ConfigJdbc.TAB_PRODUITS)
public class Produit {
 
// fields
@Id
@Column(name = ConfigJdbc.TAB_PRODUITS_ID)
private Long id;

L'entità [Product2] è associata alla tabella [PRODUCTS2] con generazione automatica delle chiavi primarie:


@Entity(name = "Produit2")
@Table(name = ConfigJdbc.TAB_PRODUITS2)
public class Produit2 {
 
// fields
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = ConfigJdbc.TAB_PRODUITS_ID)
private Long id;

Inoltre, il progetto che genera il database [dbproduits] deve essere modificato per indicare che ora nel database sono presenti due entità JPA:

  

Il file [persistence.xml] viene modificato come segue:


<?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">
        <!-- entities 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>

Il progetto [generic-create-dbproduits] è comune a tutti i DBMS. Il livello JPA di quelli esaminati in precedenza non disponeva dell'entità [Product2]. Ci si potrebbe quindi chiedere se il riferimento a un'entità JPA inesistente causi il fallimento del progetto per questi DBMS. I test dimostrano che non è così.

Una volta apportate queste modifiche, l'esecuzione della configurazione [spring-jpa-generic-JUnitTestDao-openjpa] dovrebbe avere esito positivo.

13.4. Configurazione del livello JPA di Hibernate

 

Nota: premere [Alt-F5] per rigenerare tutti i progetti Maven.

Il progetto [sqlserver-config-jpa-hibernate] è analogo al progetto [mysql-config-jpa-hibernate] (Sezione 6.3) con le stesse modifiche utilizzate per portare il progetto [mysql-config-jpa-openjpa] al progetto [sqlserver-config-jpa-openjpa] (Sezione 8.3).

Una volta apportate queste modifiche, l'esecuzione della configurazione [spring-jpa-generic-JUnitTestDao-hibernate-eclipselink] dovrebbe avere esito positivo.

 

Nota: premere [Alt-F5] per rigenerare tutti i progetti Maven.

Il progetto [sqlserver-config-jpa-eclipselink] è analogo al progetto [mysql-config-jpa-eclipselink] (Sezione 7.3) e presenta le stesse modifiche utilizzate per il porting del progetto [mysql-config-jpa-openjpa] al progetto [sqlserver-config-jpa-openjpa] (Sezione 8.3).

Una volta apportate queste modifiche, l'esecuzione della configurazione [spring-jpa-generic-JUnitTestDao-hibernate-eclipselink] dovrebbe avere esito positivo.