Skip to content

13. SQL Server 2014

Тепер перейдемо до перенесення на SQL Server 2014 того, що було зроблено з MySQL.

13.1. Налаштування робочого середовища

13.1.1. Середовище Eclipse

Ми працюватимемо з таким середовищем Eclipse:

  

Вищезазначені проекти SQL Server знаходяться у папці [<exemples>/spring-database-config\sqlserver\eclipse].

Примітка: виконайте команду [Alt-F5], щоб перегенерувати всі проекти Maven.

13.1.2. Створення баз даних

Як це було зроблено з Oracle та DB2, нам доведеться встановити драйвер JDBC для сервера SQL у локальне сховище Maven.

  

Файл [install.bat] містить такий код:

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

де [%M2-HOME%] — це папка інсталяції Maven (див. параграф 23.2, сторінка 466). Після цієї інсталяції драйвер JDBC сервера SQL можна вказати у файлах [pom.xml] за допомогою такої залежності:


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

У подальшому підключення до баз даних SQL та SERVER здійснюється за допомогою облікових даних [sa / msde]. Запустіть сервер SQL та його клієнт [MsManager] (див. параграф 23.9).

  • у [1] завантажте скрипт SQL [<exemples>\spring-database-config\sqlserver\databases\dbproduits.sql] ;
  • у [2] не вдалося використати ту саму таблицю [PRODUITS] для проектів [spring-jdbc-01 à 03]. Причина полягає в тому, що:
    • проєкти [spring-jdbc-01 et 02] вставляють рядки зі своїми первинними ключами;
    • проект [spring-jdbc-03] вставляє рядки без первинних ключів і очікує, що SGBD їх згенерує. Для цього первинний ключ [ID] повинен бути типу [Identity]. Однак цей тип у SQL Server підтримує лише автоматичне генерування первинних ключів і не дозволяє вставляти запис із первинним ключем, заданим користувачем. У цьому випадку з’являється повідомлення про помилку, і мені не вдалося її обійти. Проєкти [spring-jdbc-01 et 02] використовують таблицю [PRODUITS] без автоматичного генерування первинних ключів. Проєкт [spring-jdbc-03] використовує таблицю [PRODUITS2] з автоматичним генеруванням первинних ключів.

Тепер виконайте наступні конфігурації:

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

Усі вони мають виконатися успішно.

Тепер створимо базу [dbproduitscategories]. Повторіть для [dbproduitscategories] процедуру, виконану для створення [dbproduits]. Скрипт SQL, який потрібно завантажити, знаходиться за адресою [<exemples>\spring-database-config\sqlserver\databases\ dbproduitscategories.sql];

  

Тепер виконайте налаштування:

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

Обидві повинні виконатися успішно.

13.2. Налаштування рівня JDBC

 

Проєкт [sqlserver-config-jdbc] налаштовує рівень [JDBC] у такій архітектурі тестування:

Цей проект аналогічний проекту конфігурації [mysql-config-jdbc] для рівня JDBC у SGBD MySQL (див. розділ 3.3). Ми наводимо лише зміни:

Файл [pom.xml] імпортує драйвер JDBC із сервера 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>
        <!-- змінні залежності ********************************************** -->
        <!-- драйвер JDBC для SGBD -->
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>sqljdbc4</artifactId>
            <version>4.0</version>
        </dependency>
        <!-- постійні залежності ********************************************** -->
        ...
    </dependencies>
...
</project>
  • рядки 18–22: драйвер JDBC із сервера SQL;

Друга зміна стосується класу [ConfigJdbc], який визначає ідентифікатори доступу до баз даних:


    // параметри підключення
    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";

Третя зміна, яку можна внести, стосується максимальної кількості параметрів, які може підтримувати [PreparedStatement]:


    // максимальна кількість параметрів [PreparedStatement]
    public final static int MAX_PREPAREDSTATEMENT_PARAMETERS = 2000;

Тест [JUnitTestPushTheLimits] генерує запити SQL на 5000 товарів, які, у свою чергу, генерують [PreparedStatement] з 5000 параметрами. MySQL підтримував це значення. Сервер SQL видав помилку, в якій вказувалося, що цей ліміт становить 2100.

Четверта зміна стосується таблиці, яку використовує проект [spring-jdbc-03]. Це вже не [PRODUITS], а [PRODUITS2]:


    // команди 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. Конфігурація шару JPA OpenJpa

 

Проєкт [sqlserver-config-jpa-openjpa] налаштовує рівень [JPA] тестової архітектури:

Цей проект аналогічний проекту конфігурації [mysql-config-jpa-openjpa] для рівня JPA OpenJpa SGBD MySQL (див. параграф 8.3). Дійсно, обидва SGBD використовують анотацію [@GeneratedValue(strategy = GenerationType.IDENTITY)] для генерації первинних ключів. Необхідно внести дві зміни. Вони містяться у визначенні біна [jpaVendorAdapter] класу [ConfigJpa]:


    // провайдер JPA
    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        OpenJpaVendorAdapter openJpaVendorAdapter = new OpenJpaVendorAdapter();
        openJpaVendorAdapter.setShowSql(false);
        openJpaVendorAdapter.setDatabase(Database.SQL_SERVER);
        openJpaVendorAdapter.setGenerateDdl(true);
        return openJpaVendorAdapter;
}
  • рядок 6: реалізацію JPA вказують, що вона працюватиме з базою даних SQL Server. Реалізація JPA після цього перейме як власні типи даних, так і SQL, що належить цьому SGBD.

Друга зміна стосується сутностей JPA, пов’язаних із таблицями [PRODUITS] та [PRODUITS2]:

  

Об’єкт [Produit] пов’язаний із таблицею [PRODUITS] без автоматичного формування первинних ключів (відсутність позначення [@GeneratedValue]):


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

// поля
@Id
@Column(name = ConfigJdbc.TAB_PRODUITS_ID)
private Long id;

Об'єкт [Produit2] пов'язаний з таблицею [PRODUITS2] з автоматичним генеруванням первинних ключів:


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

// поля
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = ConfigJdbc.TAB_PRODUITS_ID)
private Long id;

Крім того, проект, який генерує базу даних [dbproduits], потрібно змінити, щоб вказати, що тепер у базі даних є дві сутності JPA:

  

Файл [persistence.xml] змінюється наступним чином:


<?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">
        <!-- об’єкти 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>

Проєкт [generic-create-dbproduits] є спільним для всіх SGBD. У шарі JPA тих, що розглядалися раніше, не було об’єкта [Produit2]. Тож можна задатися питанням, чи не призведе посилання на неіснуючий об’єкт JPA до збою проекту для цих SGBD. Тестування показує, що ні.

Після внесення цих змін виконання конфігурації [spring-jpa-generic-JUnitTestDao-openjpa] має пройти успішно.

13.4. Конфігурація шару JPA Hibernate

 

Примітка: виконайте команду [Alt-F5], щоб перегенерувати всі проекти Maven.

Проєкт [sqlserver-config-jpa-hibernate] аналогічний проєкту [mysql-config-jpa-hibernate] (параграф 6.3) і містить ті самі зміни, що були застосовані під час перенесення [mysql-config-jpa-openjpa] до проєкту [sqlserver-config-jpa-openjpa] (параграф 8.3).

Після внесення цих змін виконання конфігурації [spring-jpa-generic-JUnitTestDao-hibernate-eclipselink] має пройти успішно.

 

Примітка: виконайте [Alt-F5], щоб перегенерувати всі проекти Maven.

Проєкт [sqlserver-config-jpa-eclipselink] аналогічний проєкту [mysql-config-jpa-eclipselink] (параграф 7.3) і містить ті самі зміни, що були застосовані під час перенесення [mysql-config-jpa-openjpa] до проєкту [sqlserver-config-jpa-openjpa] (параграф 8.3).

Після внесення цих змін виконання конфігурації [spring-jpa-generic-JUnitTestDao-hibernate-eclipselink] має пройти успішно.