Skip to content

13. SQL سرور ۲۰۱۴

اکنون به انتقال کاری که روی MySQL انجام شده به SQL Server 2014 می‌پردازیم.

13.1. راه‌اندازی محیط کاری

13.1.1. محیط اکلیپس

ما با محیط اکلیپس زیر کار خواهیم کرد:

  

پروژه‌های سرور SQL که در بالا فهرست شده‌اند را می‌توان در پوشه [<exemples>/spring-database-config\sqlserver\eclipse] یافت.

توجه: برای بازتولید مجدد تمام پروژه‌های Maven، [Alt-F5] را اجرا کنید.

13.1.2. ایجاد پایگاه داده

همان‌طور که با Oracle و DB2 انجام شد، باید درایور JDBC برای SQL Server را در مخزن محلی 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 تنها از تولید خودکار کلیدهای اصلی پشتیبانی می‌کند و اجازه درج ردیف با کلید اصلی تعریف‌شده توسط کاربر را نمی‌دهد. سپس یک خطا گزارش می‌شود و من نتوانسته‌ام راه‌حلی برای آن پیدا کنم. پروژه‌های [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] را ایجاد کنیم. رویهٔ ایجاد [dbproduits] را برای [dbproduitscategories] تکرار کنید. اسکریپت 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>
  • خطوط ۱۸–۲۲: درایور 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] سفارش‌هایی برای ۵۰۰۰ محصول ایجاد می‌کند که این امر منجر به ایجاد [PreparedStatement] با ۵۰۰۰ پارامتر می‌شود. MySQL از این مقدار پشتیبانی می‌کرد. سرور SQL خطایی را بازگرداند که اعلام می‌کرد این محدودیت روی ۲۱۰۰ تنظیم شده است.

تغییر چهارم مربوط به جدولی است که توسط پروژه [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 از anotation [@GeneratedValue(strategy = GenerationType.IDENTITY)] برای تولید کلیدهای اصلی استفاده می‌کنند. دو تغییر باید انجام شود. این تغییرات در تعریف bean [jpaVendorAdapter] از کلاس [ConfigJpa] قرار دارند:


    // ارائه‌دهنده JPA
    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        OpenJpaVendorAdapter openJpaVendorAdapter = new OpenJpaVendorAdapter();
        openJpaVendorAdapter.setShowSql(false);
        openJpaVendorAdapter.setDatabase(Database.SQL_SERVER);
        openJpaVendorAdapter.setGenerateDdl(true);
        return openJpaVendorAdapter;
}
  • خط ۶: به پیاده‌سازی JPA دستور داده می‌شود که با پایگاه داده سرور SQL کار کند. پیاده‌سازی JPA سپس هر دو نوع داده اختصاصی و SQL را که مالک این SGBD است، اتخاذ خواهد کرد.

تغییر دوم مربوط به موجودیت‌های JPA است که با جداول [PRODUITS] و [PRODUITS2] مرتبط هستند:

  

اینتیتی [Produit] با جدول [PRODUITS] مرتبط است بدون تولید خودکار کلیدهای اصلی (بدون ورودی [@GeneratedValue]):


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

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

این موجودیت [Produit2] با جدول [PRODUITS2] مرتبط است و کلیدهای اصلی به‌صورت خودکار تولید می‌شوند:


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

علاوه بر این، پروژه‌ای که پایگاه داده [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. پیکربندی لایه Hibernate JPA

 

توجه: برای بازتولید تمام پروژه‌های Maven، [Alt-F5] را اجرا کنید.

پروژه [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] باید موفقیت‌آمیز باشد.

 

توجه: برای بازتولید مجدد تمام پروژه‌های Maven، [Alt-F5] را اجرا کنید.

پروژه [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] باید با موفقیت انجام شود.