Skip to content

13. SQL Server 2014

سنناقش الآن نقل ما تم تنفيذه مع MySQL إلى SQL Server 2014.

13.1. إعداد بيئة العمل

13.1.1. بيئة Eclipse

سنعمل باستخدام بيئة Eclipse التالية:

  

يمكن العثور على مشاريع SQL Server المذكورة أعلاه في المجلد [<examples>/spring-database-config\sqlserver\eclipse].

ملاحظة: اضغط على [Alt-F5] لإعادة إنشاء جميع مشاريع Maven.

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.الصفحة 466). بعد هذا التثبيت، يمكن الإشارة إلى برنامج تشغيل JDBC لـ SQL Server في ملفات [pom.xml] باستخدام التبعية التالية:


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

في بقية هذا الدليل، تتم الاتصالات بقاعدة بيانات SQL Server باستخدام بيانات الاعتماد [sa / msde]. قم بتشغيل SQL Server وعميله [MsManager] (انظر القسم 23.9).

  • في [1]، قم بتحميل البرنامج النصي SQL [<examples>\spring-database-config\sqlserver\databases\dbproduits.sql
  • في [2]، لم يكن من الممكن استخدام نفس جدول [PRODUCTS] للمشاريع [spring-jdbc-01 إلى 03]. والسبب هو أن:
    • المشاريع [spring-jdbc-01 و 02] تقوم بإدراج صفوف بمفاتيحها الأساسية؛
    • المشروع [spring-jdbc-03] يُدخل صفوفًا بدون مفاتيح أساسية ويتوقع من نظام إدارة قواعد البيانات (DBMS) أن يقوم بإنشائها. لكي يعمل هذا، يجب أن يكون المفتاح الأساسي [ID] من النوع [Identity]. ومع ذلك، فإن هذا النوع في SQL Server يدعم فقط الإنشاء التلقائي للمفاتيح الأساسية ولا يسمح بإدخال صف بمفتاح أساسي محدد من قبل المستخدم. ثم يتم الإبلاغ عن خطأ، ولم أتمكن من التغلب عليه. يستخدم مشروعا [spring-jdbc-01 و 02] جدول [PRODUCTS] بدون إنشاء تلقائي للمفاتيح الأساسية. يستخدم مشروع [spring-jdbc-03] جدول [PRODUCTS2] مع إنشاء تلقائي للمفاتيح الأساسية.

الآن، قم بتشغيل التكوينات:

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

يجب أن تنجح جميعها.

الآن دعونا ننشئ قاعدة البيانات [dbproduitscategories]. كرر الإجراء المستخدم لإنشاء [dbproduits] لـ [dbproduitscategories]. يوجد نص SQL المطلوب تحميله في [<examples>\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 لنظام إدارة قواعد البيانات MySQL (انظر القسم 3.3). ونعرض هنا التغييرات فقط:

يستورد ملف [pom.xml] برنامج تشغيل JDBC لـ 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>
  • الأسطر 18-22: برنامج تشغيل JDBC لـ SQL Server؛

التغيير الثاني في فئة [ConfigJdbc]، التي تحدد بيانات اعتماد قاعدة البيانات:


    // 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";

التعديل الثالث الذي يمكن إجراؤه هو على الحد الأقصى لعدد المعلمات التي يمكن أن يدعمها [PreparedStatement]:


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

يُنشئ الاختبار [JUnitTestPushTheLimits] عبارات SQL لـ 5,000 منتج، مما سيؤدي إلى إنشاء كائنات [PreparedStatement] تحتوي على 5,000 معلمة. وقد دعمت قاعدة بيانات MySQL هذه القيمة. أما SQL Server فقد أرجعت خطأً يشير إلى أن هذا الحد الأقصى هو 2,100.

التغيير الرابع هو في الجدول الذي يستخدمه مشروع [spring-jdbc-03]. لم يعد [PRODUCTS] بل [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. تكوين طبقة OpenJPA JPA

 

يقوم مشروع [sqlserver-config-jpa-openjpa] بتكوين طبقة [JPA] في بنية الاختبار:

هذا المشروع مشابه لمشروع التكوين [mysql-config-jpa-openjpa] الخاص بطبقة OpenJpa JPA لنظام إدارة قواعد البيانات MySQL (انظر القسم 8.3). في الواقع، يستخدم كل من نظامي إدارة قواعد البيانات (DBMS) التعليق التوضيحي [@GeneratedValue(strategy = GenerationType.IDENTITY)] لإنشاء مفاتيح أساسية. هناك تغييران يجب إجراؤهما. وهما موجودان في تعريف حبة [jpaVendorAdapter] في فئة [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;
}
  • السطر 6: نخبر تطبيق JPA أنه سيعمل مع قاعدة بيانات SQL Server. سيقوم تطبيق JPA بعد ذلك بتبني كل من أنواع البيانات الخاصة ولسان SQL الخاص بنظام إدارة قواعد البيانات هذا.

التغيير الثاني يتعلق بكيانات JPA المرتبطة بجداول [PRODUCTS] و [PRODUCTS2]:

  

الكيان [Product] مرتبط بجدول [PRODUCTS] دون إنشاء مفاتيح أساسية تلقائيًا (بدون تعليق [@GeneratedValue]):


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

الكيان [Product2] مرتبط بالجدول [PRODUCTS2] مع إنشاء مفاتيح أساسية تلقائيًا:


@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">
        <!-- 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>

مشروع [generic-create-dbproduits] مشترك بين جميع أنظمة إدارة قواعد البيانات. طبقة JPA في الأنظمة التي تم فحصها سابقًا لم تكن تحتوي على كيان [Product2]. قد يتساءل المرء إذن عما إذا كانت الإشارة إلى كيان JPA غير موجود ستؤدي إلى فشل المشروع في هذه الأنظمة. تظهر الاختبارات أن هذا لا يحدث.

بعد إجراء هذه التغييرات، من المفترض أن ينجح تنفيذ تكوين [spring-jpa-generic-JUnitTestDao-openjpa].

13.4. تكوين طبقة Hibernate JPA

 

ملاحظة: اضغط على [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].