Skip to content

13. SQL Server 2014

Ahora abordamos la migración a SQL Server 2014 de lo que se ha hecho con MySQL.

13.1. Configuración del entorno de trabajo

13.1.1. Entorno Eclipse

Trabajaremos con el siguiente entorno de Eclipse:

  

Los proyectos SQL Server mencionados anteriormente se encuentran en la carpeta [<exemples>/spring-database-config\sqlserver\eclipse].

Nota: ejecuta [Alt-F5] para regenerar todos los proyectos de Maven.

13.1.2. Generación de las bases de datos

Al igual que se hizo con Oracle y DB2, tendremos que instalar el controlador JDBC de SQL Server en el repositorio local de Maven.

  

El archivo [install.bat] contiene el siguiente código:

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

donde [%M2-HOME%] es la carpeta de instalación de Maven (véase el párrafo 23.2, página 466). Tras esta instalación, el controlador JDBC de SQL Server puede referenciarse en los archivos [pom.xml] mediante la siguiente dependencia:


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

A partir de este momento, la conexión a las bases de datos SQL y SERVER se realiza con las credenciales [sa / msde]. Inicie el servidor SQL y su cliente [MsManager] (véase el párrafo 23.9).

  • en [1], cargue el script SQL [<exemples>\spring-database-config\sqlserver\databases\dbproduits.sql];
  • en [2], no fue posible utilizar la misma tabla [PRODUITS] para los proyectos [spring-jdbc-01 à 03]. La razón es que:
    • los proyectos [spring-jdbc-01 et 02] insertan filas con sus claves primarias;
    • el proyecto [spring-jdbc-03] inserta filas sin claves primarias y espera que el SGBD las genere. Para ello, es necesario que la clave primaria [ID] sea del tipo [Identity]. Sin embargo, este tipo en SQL Server solo admite la generación automática de claves primarias y no permite la inserción de una fila con una clave primaria definida por el usuario. En ese caso, se reporta un error y no he podido solucionarlo. Los proyectos [spring-jdbc-01 et 02] utilizan la tabla [PRODUITS] sin generación automática de claves primarias. El proyecto [spring-jdbc-03] utiliza la tabla [PRODUITS2] con generación automática de claves primarias.

Ahora ejecuta las configuraciones:

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

Todas deben ejecutarse correctamente.

Ahora generemos la base [dbproduitscategories]. Repite para [dbproduitscategories] el procedimiento que realizaste para crear [dbproduits]. El script SQL que se debe cargar se encuentra en la ubicación [<exemples>\spring-database-config\sqlserver\databases\ dbproduitscategories.sql];

  

Ahora, ejecute las configuraciones:

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

Ambas deben completarse con éxito.

13.2. Configuración de la capa JDBC

 

El proyecto [sqlserver-config-jdbc] configura la capa [JDBC] de la siguiente arquitectura de pruebas:

El proyecto es similar al proyecto de configuración [mysql-config-jdbc] de la capa JDBC del SGBD MySQL (véase el párrafo 3.3). Solo presentamos las modificaciones:

El archivo [pom.xml] importa el controlador JDBC del servidor SQL:


<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>
        <!-- dependencias variables ********************************************** -->
        <!-- controlador JDBC del SGBD -->
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>sqljdbc4</artifactId>
            <version>4.0</version>
        </dependency>
        <!-- dependencias constantes ********************************************** -->
        ...
    </dependencies>
...
</project>
  • líneas 18-22: el controlador JDBC del servidor SQL;

La segunda modificación se encuentra en la clase [ConfigJdbc], que define las credenciales de acceso a las bases de datos:


    // parámetros de conexión
    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 tercera modificación que se puede realizar es la del número máximo de parámetros que un [PreparedStatement] puede admitir:


    // número máximo de parámetros de un [PreparedStatement]
    public final static int MAX_PREPAREDSTATEMENT_PARAMETERS = 2000;

La prueba [JUnitTestPushTheLimits] genera órdenes SQL para 5000 productos, las cuales a su vez generarán [PreparedStatement] con 5000 parámetros. MySQL había soportado este valor. El servidor SQL generó un error indicando que este límite era de 2100.

La cuarta modificación se encuentra en la tabla utilizada por el proyecto [spring-jdbc-03]. Ya no es [PRODUITS], sino [PRODUITS2]:


    // órdenes 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. Configuración de la capa JPA OpenJpa

 

El proyecto [sqlserver-config-jpa-openjpa] configura la capa [JPA] de la arquitectura de pruebas:

El proyecto es análogo al proyecto de configuración [mysql-config-jpa-openjpa] de la capa JPA OpenJpa del SGBD MySQL (véase el párrafo 8.3). De hecho, ambos SGBD utilizan la anotación [@GeneratedValue(strategy = GenerationType.IDENTITY)] para generar las claves primarias. Hay que realizar dos modificaciones. Se encuentran en la definición del bean [jpaVendorAdapter] de la clase [ConfigJpa]:


    // el proveedor JPA
    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        OpenJpaVendorAdapter openJpaVendorAdapter = new OpenJpaVendorAdapter();
        openJpaVendorAdapter.setShowSql(false);
        openJpaVendorAdapter.setDatabase(Database.SQL_SERVER);
        openJpaVendorAdapter.setGenerateDdl(true);
        return openJpaVendorAdapter;
}
  • línea 6: se le indica a la implementación JPA que va a trabajar con una base de datos SQL Server. La implementación JPA adoptará entonces tanto los tipos de datos propios como el SQL propio de este SGBD.

La segunda modificación se refiere a las entidades JPA asociadas a las tablas [PRODUITS] y [PRODUITS2]:

  

La entidad [Produit] está asociada a la tabla [PRODUITS] sin generación automática de claves primarias (ausencia de la notación [@GeneratedValue]):


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

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

La entidad [Produit2] está asociada a la tabla [PRODUITS2] con generación automática de claves primarias:


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

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

Además, el proyecto que genera la base de datos [dbproduits] debe modificarse para indicar que ahora hay dos entidades JPA en la base de datos:

  

El archivo [persistence.xml] cambia de la siguiente manera:


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

El proyecto [generic-create-dbproduits] es común a todos los SGBD. La capa JPA de los analizados anteriormente no contaba con la entidad [Produit2]. Entonces, cabe preguntarse si el hecho de hacer referencia a una entidad JPA inexistente no provocará un error en el proyecto para estos SGBD. Las pruebas demuestran que no.

Una vez realizadas estas modificaciones, la ejecución de la configuración [spring-jpa-generic-JUnitTestDao-openjpa] debería completarse con éxito.

13.4. Configuración de la capa JPA de Hibernate

 

Nota: ejecute [Alt-F5] para regenerar todos los proyectos de Maven.

El proyecto [sqlserver-config-jpa-hibernate] es similar al proyecto [mysql-config-jpa-hibernate] (párrafo 6.3) y cuenta con las mismas modificaciones que se aplicaron al portar el proyecto [mysql-config-jpa-openjpa] al proyecto [sqlserver-config-jpa-openjpa] (párrafo 8.3).

Una vez realizadas estas modificaciones, la ejecución de la configuración [spring-jpa-generic-JUnitTestDao-hibernate-eclipselink] debería completarse con éxito.

 

Nota: ejecute [Alt-F5] para regenerar todos los proyectos de Maven.

El proyecto [sqlserver-config-jpa-eclipselink] es similar al proyecto [mysql-config-jpa-eclipselink] (párrafo 7.3) con las mismas modificaciones que se aplicaron al portar el proyecto [mysql-config-jpa-openjpa] al proyecto [sqlserver-config-jpa-openjpa] (párrafo 8.3).

Una vez realizadas estas modificaciones, la ejecución de la configuración [spring-jpa-generic-JUnitTestDao-hibernate-eclipselink] debería completarse con éxito.