Skip to content

1. مقدمة

ملف PDF لهذا المستند متاح |هنا||.

الأمثلة الواردة في هذا المستند متاحة |هنا|.

1.1. المحتويات

في هذا المستند، نقترح دراسة تكوينات مختلفة لنشر قواعد البيانات. ضع في اعتبارك البنية الطبقية التالية:

يتحرك مسار التنفيذ من اليسار إلى اليمين:

  • يتم تنفيذ إحدى الفئات في طبقة [ui] (واجهة المستخدم) أولاً. وهي تقوم بإنشاء مثيلات لطبقتي [business] و[DAO]. إذا كانت طبقة [ui] عبارة عن واجهة مستخدم رسومية، فإنها تنتظر عندئذٍ إجراءات المستخدم. يمكن لإجراء المستخدم أن يؤدي إلى تنفيذ طرق عبر جميع طبقات البنية وصولاً إلى قاعدة البيانات. يتم إرجاع نتيجة هذه التنفيذات إلى المستخدم بشكل أو بآخر؛

قد تكون أدوار الطبقات المختلفة كما يلي:

  • طبقة [JDBC] (اتصال قاعدة بيانات جافا) هي واجهة وصول عالمية لقاعدة البيانات. وهي تقدم دائمًا نفس الواجهة لطبقة [DAO]. إذا قمت بتبديل أنظمة إدارة قواعد البيانات (DBMS)، فما عليك سوى تغيير برنامج تشغيل JDBC. تظل طبقة [DAO] دون تغيير إذا كنت قد حرصت على اتباع مجموعة معينة من القواعد. ومع ذلك، من الصعب ضمان قابلية النقل بنسبة 100٪ بين أنظمة إدارة قواعد البيانات (DBMS) لأنها غالبًا ما تحتوي على كمية كبيرة من لغة SQL الخاصة التي يصعب تجاهلها، حيث إنها غالبًا ما توفر مكاسب في الأداء. بمجرد استخدام لغة SQL الخاصة، تصبح قابلية النقل بين أنظمة إدارة قواعد البيانات (DBMS) غير ممكنة. علاوة على ذلك، غالبًا ما يكون لأنظمة إدارة قواعد البيانات (DBMS) سياسات مختلفة لتوليد المفاتيح الأساسية تلقائيًا، بالإضافة إلى كلمات رئيسية محجوزة تختلف من نظام لآخر. ومع ذلك، فقد نجحنا في هذا المستند في نقل بنية JDBC المدروسة إلى ستة أنظمة إدارة قواعد بيانات (DBMS) مختلفة من خلال قبول الحاجة إلى مشروع تكوين لكل منها؛
  • تكشف طبقة [DAO] عن واجهة للوصول إلى البيانات من قاعدة البيانات المحددة المستخدمة (ليتم تمييزها عن واجهة JDBC، التي تكشف عن طرق صالحة لأي نظام إدارة قواعد البيانات)؛
  • تنفذ طبقة [الأعمال] قواعد إدارة التطبيق أو قواعد الأعمال.
    • تتكون بيانات الإدخال الخاصة بها من بيانات من قاعدة البيانات عبر طبقة [DAO] و/أو مدخلات المستخدم التي ترسل إليها طبقة [UI
    • تنتج بيانات يمكنها حفظها في قاعدة البيانات عبر طبقة [DAO] و/أو إرجاعها إلى طبقة [UI] التي استعلمت عنها، لعرضها على المستخدم؛
  • طبقة [UI] هي الطبقة التي تنفذ إجراءات المستخدم وتعيد نتائج تلك الإجراءات إلى المستخدم؛

أعلاه، ترسل طبقة [DAO] استعلامات SQL إلى طبقة [JDBC] لتنفيذها في نظام إدارة قواعد البيانات (DBMS). في السنوات الأخيرة (منذ عام 2006)، تطورت هذه البنية على النحو التالي:

أصبحت طبقة JPA (واجهة برمجة تطبيقات الاستمرارية في Java) هي التي ترسل استعلامات SQL إلى طبقة JDBC وتستقبل النتائج. تقدم طبقة [JPA] العمليات إلى طبقة [DAO] من أجل تخزين الكائنات وتعديلها وحذفها واسترجاعها. لم تعد طبقة [DAO] تصدر أوامر SQL. هذا النهج أكثر قابلية للنقل لأن تطبيقات JPA تتعامل مع الاختلافات بين أنظمة إدارة قواعد البيانات، ولكنه أبطأ من تقنية JDBC. سنجري اختبارات أداء لإثبات ذلك. تعمل تقنية JPA على إضفاء الطابع الرسمي على العمل الذي أنجزه إطار عمل Hibernate [http://hibernate.org/] منذ سنوات.

سنقوم بفحص طبقتين [DAO] باستخدام إحدى البنيتين التاليتين:

سنحتاج إلى أن تنفذ طبقتا [DAO1] و[DAO2] نفس واجهة [IDAO]. وبالتالي، سيكون اختبار [JUnitTestsDao] هو نفسه في كلا التكوينين، مما سيسمح لنا بمقارنة الأداء. وسيتم تنفيذ طبقة [DAO1] باستخدام Spring JDBC، بينما ستنفذ طبقة [DAO2] باستخدام Spring JPA؛

بمجرد الانتهاء من ذلك، سنعرض واجهة [IDAO] على الويب على النحو التالي:

  • في [1]، يتم عرض طبقة [IDAO] على الويب من خلال طبقة ويب [2] تم تنفيذها بواسطة Spring MVC. إنها بالفعل واجهة [IDAO] التي يتم عرضها، وسنقوم ببناء نسختين من خدمة الويب اعتمادًا على ما إذا كانت هذه الواجهة قد تم تنفيذها باستخدام بنية [DAO-JDBC] أو [DAO-JPA-JDBC
  • في [B]، يستخدم عميل بعيد عناوين URL التي تعرضها خدمة الويب، والتي توفر الوصول إلى أساليب طبقة [IDAO-server]. سنضمن أن طبقة [DAO-Client] [3] تنفذ واجهة [IDAO-server] [1]. سيسمح لنا ذلك باستخدام نفس اختبار [JUnitTestsDao] الذي تم استخدامه مرتين بالفعل [4]؛
  • في [3]، سيتم تنفيذ طبقة [DAO-Client] باستخدام Spring RestTemplate؛

بمجرد الانتهاء من ذلك، سنقوم بتأمين الوصول إلى خدمة الويب:

  • في [5]، يمر طلب HTTP الخاص بالعميل عبر طبقة مصادقة تم تنفيذها باستخدام Spring Security؛

بمجرد الانتهاء من ذلك، سنطور البنية السابقة لتصبح كما يلي:

  • في [3]، يعد تطبيق العميل بحد ذاته تطبيق ويب. وسيتضمن نموذجًا [5] يتيح للمستخدمين الاستعلام عن عناوين URL لخدمة الويب الآمنة. وسيتم التعامل مع الوصول عبر HTTP إلى خدمة الويب الآمنة من خلال طبقة [DAO-client-js] مطبقة بلغة JavaScript. تستخدم هذه البنية ما يُعرف باسم الطلبات عبر المجالات:
    • توفر خدمة الويب [2] عناوين URL على شكل [http://machine1:port1/
    • يتم تنزيل تطبيق الويب العميل [3] من عنوان URL [http://machine2:port2/]. إذا لم يكن [http://machine2:port2/] مطابقًا لـ [http://machine1:port1/] (نفس الجهاز، نفس المنفذ)، فسيقوم متصفح العميل بحظر مكالمات HTTP من طبقة [DAO-client-js]. لحل هذه المشكلة، يجب أن تسمح خدمة الويب بالطلبات عبر النطاقات. سنرى كيف؛

تم اختبار المشاريع المعروضة باستخدام أنظمة إدارة قواعد البيانات الستة التالية:

  • MySQL 5 Community Edition؛
  • SQL Server 2014 Express؛
  • PostgreSQL 9.4؛
  • Oracle Express 11g الإصدار 2؛
  • IBM DB2 Express-C 10.5؛
  • Firebird 2.5.4؛

بالنسبة لكل نظام من أنظمة إدارة قواعد البيانات هذه، قمنا بتطوير أربع طبقات [DAO] مختلفة:

  • طبقة تم تنفيذها باستخدام Spring JDBC؛
  • طبقة تم تنفيذها باستخدام Spring JPA ومزود Hibernate JPA؛
  • طبقة تم تنفيذها باستخدام Spring JPA ومزود EclipseLink JPA؛
  • طبقة تم تنفيذها باستخدام Spring JPA ومزود OpenJPA JPA؛

وبالتالي، يتم هنا عرض مجموعة من أربعة وعشرين تكوينًا مختلفًا. وقد بذلنا جهدًا كبيرًا لتبسيط الكود:

  • معظم الكود مكتوب مرة واحدة فقط. وهو يعتمد على مشروعي تكوين Maven:
    • أحدهما يهيئ طبقة JDBC؛
    • والآخر يقوم بتكوين طبقة JPA؛

يتكون مشروع تكوين Maven لطبقة JDBC [1] لنظام إدارة قواعد البيانات (DBMS) معين من خطوتين:

  • استيراد أرشيف برنامج تشغيل JDBC؛
  • تحديد بيانات اعتماد الوصول لقاعدة البيانات المستخدمة وعبارات SQL المختلفة التي سترسلها طبقة [DAO1] إلى برنامج تشغيل JDBC. على الرغم من أن لغة SQL موحدة، فقد واجهنا مشكلات في قابلية النقل، ويرجع ذلك أساسًا إلى وجود أسماء جداول/أعمدة في الاستعلامات تبين أنها كلمات رئيسية محظورة في أنظمة إدارة قواعد البيانات (DBMS) معينة (جدول ROLES في DB2، وعمود PASSWORD في Firebird). علاوة على ذلك، على الرغم من أن اسم العمود عادةً ما يكون غير حساس لحالة الأحرف (كبيرة/صغيرة)، فقد واجهنا مشكلة مع PostgreSQL فيما يتعلق بعمود ID للمفتاح الأساسي في الجداول. فقد تطلب الأمر تسميته "id" بأحرف صغيرة. هذه أمثلة نموذجية لمشاكل قابلية النقل غير المتوقعة؛

تتكون مشاريع Maven الثلاثة لتكوين طبقة JPA [2] لنظام إدارة قواعد بيانات معين أيضًا من خطوتين:

  • استيراد أرشيف تنفيذ JPA؛
  • تكوين تطبيق JPA المستخدم لنظام إدارة قواعد البيانات (DBMS) المحدد المتصل. في الواقع، طبقة JPA هي التي تصدر أوامر SQL إلى طبقة JDBC. لكي تكون فعالة، يجب أن تعرف نظام إدارة قواعد البيانات (DBMS) من أجل إرسال أوامر SQL التي سيتعرف عليها. قد تستخدم هذه الأوامر لغة SQL الخاصة بنظام إدارة قواعد البيانات (DBMS) بالإضافة إلى ميزاته المحددة (أنواع البيانات، التسلسلات، المشغلات، الإجراءات، التوليد التلقائي للمفاتيح الأساسية، إلخ)؛

ينتج عن ذلك أربعة وعشرون مشروع تكوين Maven (4 تكوينات × 6 أنظمة إدارة قواعد البيانات) ستستند إليها جميع مشاريع تشغيل قواعد البيانات الأخرى. في المخططات أعلاه، نظرًا لأن طبقتي [DAO1] و[DAO2] توفران نفس الواجهة، سيتم اختبار التكوينات الـ 24 للبنيتين أعلاه باستخدام فئة اختبار واحدة [JUnitTestsDao]. بمجرد التحقق من صحة هذه البنيات، لن تكون هناك صعوبات أخرى:

  • يعتمد مشروع Maven لنشر قاعدة البيانات على الويب على هاتين البنيتين. وبالتالي، هناك أيضًا 24 تكوينًا ممكنًا هنا؛
  • يعتمد مشروع Maven لتأمين الوصول إلى خدمة الويب على المشروع السابق ويحتوي أيضًا على 24 تكوينًا ممكنًا؛
  • وأخيرًا، فإن مشروع Maven الذي يتيح إجراء طلبات عبر المجالات إلى خدمة الويب الآمنة يستند إلى المشروع السابق، كما يتضمن 24 تكوينًا ممكنًا؛

أجريت الدراسة باستخدام نظام إدارة قواعد البيانات MySQL5 وتطبيق Hibernate JPA. ثم قمنا بنقل الكود إلى تطبيقات Eclipselink و OpenJPA JPA. وأخيرًا، قمنا بنقله إلى قواعد بيانات أخرى (PostgreSQL، Oracle، SQL Server، DB2، Firebird).

هذه الدورة مخصصة للمبتدئين. يتم شرح معظم المفاهيم المستخدمة. لا يلزم وجود معرفة مسبقة ببرمجة قواعد البيانات أو برمجة الويب. ومع ذلك، من الضروري وجود فهم قوي للغة SQL، حيث لا يتم شرح استعلامات SQL المستخدمة.

لفهم الأمثلة، تحتاج إلى معرفة أساسية بلغة Java، والتي يمكن العثور عليها في أي دورة تمهيدية عن اللغة. يكفي الفصلان الأولان من الوثيقة [مقدمة إلى لغة Java]. إنها وثيقة قديمة (1998، نُقحت في 2002)، لكن الأساسيات موجودة فيها. للحصول على دورة شاملة، يمكن قراءة كتاب جان ماري دودو [http://www.jmdoudoux.fr/java].

هذا المستند ليس شاملاً بأي حال من الأحوال. الغرض منه هو فقط توفير منهجية ورمز يمكن إعادة استخدامهما في سياقات مشابهة. تمت كتابة المستند بحيث يمكن قراءته دون الحاجة إلى جهاز كمبيوتر. لذلك، تم تضمين العديد من لقطات الشاشة.

على الرغم من أن هذا المستند لا يغطي جميع إمكانيات لغة Java أو جميع مجالات تطبيقها، إلا أنه يمكن استخدامه كمورد تعليمي للغة. من خلال اتباع هذا المستند — حتى لو لم يكن بالكامل — سيصل القارئ المبتدئ إلى مستوى "Java المتقدم" في كل من استخدام اللغة وإطار عمل Spring. يمكنهم بعد ذلك مواصلة تدريبهم على Java باستخدام الكتب التالية:

  • [Spring MVC and Thymeleaf by Example] [https://stahe.github.io/ar-springmvc-thymeleaf-janv-2015/]، الذي يواصل استكشاف نظام Spring البيئي من خلال تقديم فرع "برمجة الويب MVC" الخاص به؛
  • [AngularJS / Spring MVC Tutorial] [https://stahe.github.io/ar-spring-angular1.x-juillet-2014/]، الذي يقدم بنية ويب عميل/خادم، حيث يتم تنفيذ العميل باستخدام إطار عمل [AngularJS] والخادم باستخدام [Spring MVC
  • [مقدمة إلى Java EE]، الذي ينتقل من نظام Spring البيئي إلى بنية ويب تستند إلى JSF (Java Server Faces) و EJB (Enterprise JavaBeans
  • [مقدمة إلى برمجة أجهزة Android اللوحية] [https://stahe.github.io/ar-android-aout-2016/] الذي يصف بنية عميل/خادم، حيث يكون العميل جهازًا لوحيًا يعمل بنظام Android والخادم خدمة ويب يتم تنفيذها بواسطة Spring MVC؛

1.2. المصادر

يستند هذا المستند إلى مصدرين رئيسيين:

  • [ ref1]: [Spring MVC و Thymeleaf بالأمثلة] على الرابط [https://stahe.github.io/ar-springmvc-thymeleaf-janv-2015/]. تعيد هذه الوثيقة النظر في العمل الذي تم إنجازه وعرضه في [ref1] باستخدام قاعدة بيانات مختلفة. ببساطة، إنها تزيله من سياق برمجة الويب باستخدام Spring MVC. قررت إنشاء وثيقة منفصلة لأنني وجدت أن الكود والمنهجية المستخدمة في [ref1] لعرض قاعدة بيانات على الويب قابلة لإعادة الاستخدام؛
  • [ ref2]: [Java Persistence in Practice] على الرابط [https://stahe.github.io/ar-jpa-juin-2007/

لمعرفة المزيد عن Spring، يمكنك استخدام المراجع التالية:

يمكن للقراء الذين لا يمتلكون معرفة كافية بلغة SQL تعلم الأساسيات من كتاب [مقدمة إلى SQL مع نظام إدارة قواعد البيانات Firebird] على الرابط [https://stahe.github.io/ar-sql-firebird-janv-2006/].

1.3. الأدوات المستخدمة

تم اختبار الأمثلة التالية في البيئة التالية:

  • جهاز يعمل بنظام Windows 8.1 Pro 64 بت؛
  • JDK 1.8 (القسم 23.1
  • Spring Tool Suite 3.6.3 IDE (القسم 1
  • متصفح Chrome (لم يتم استخدام متصفحات أخرى)؛
  • ملحق Chrome [Advanced Rest Client] (القسم 1
  • نظام إدارة قواعد البيانات MySQL 5.6 Community Edition (القسم 23.4
  • SQL Server 2014 Express (القسم 23.9
  • PostgreSQL 9.4 (القسم 23.7
  • نظام إدارة قواعد البيانات Oracle Express 11g Release 2 (الفقرة 23.6
  • نظام إدارة قواعد البيانات IBM DB2 Express-C 10.5 (القسم 23.8
  • نظام إدارة قواعد البيانات Firebird 2.5.4 (القسم 23.10
  • عملاء EMS Manager لهذه الأنظمة الستة لإدارة قواعد البيانات (القسم 23.5

ملاحظة بخصوص JDK 1.8: تستخدم إحدى الطرق في دراسة الحالة طريقة من حزمة [java.lang] في Java 8.

معظم الأمثلة عبارة عن مشاريع Maven يمكن فتحها في Eclipse أو IntelliJ IDEA أو NetBeans. وفيما يلي، لقطات الشاشة مأخوذة من Spring Tool Suite IDE، وهو أحد أشكال Eclipse.

1.4. الأمثلة

الأمثلة متاحة |هنا| كملف ZIP قابل للتنزيل.

  • في [1]، مجلدات الأمثلة؛
  • في [2]، يحتوي مجلد [spring-core] على مشاريع تعلم Spring؛
  • في [3]، يحتوي المجلد [spring-database-config] على مشاريع تكوين JDBC و JPA لست قواعد البيانات؛
  • في [4]، تكوين نظام إدارة قواعد البيانات Oracle. ويحتوي على ثلاثة مجلدات:
    • يحتوي [databases] على نصوص SQL لإنشاء قاعدتي البيانات المستخدمتين في الوثيقة؛
    • [jdbc-driver] يحتوي على برنامج تشغيل Oracle JDBC بالإضافة إلى نص برمجي لتثبيته في مستودع Maven المحلي؛
    • [eclipse] يحتوي [5] على مشاريع تكوين Oracle الأربعة:
      • [oracle-config-jdbc] يقوم بتكوين طبقة JDBC للوصول إلى نظام إدارة قواعد البيانات؛
      • [oracle-config-jpa-hibernate] يقوم بتكوين طبقة JPA للوصول إلى نظام إدارة قواعد البيانات باستخدام مزود Hibernate JPA؛
      • [oracle-config-jpa-eclipselink] يقوم بتكوين طبقة JPA للوصول إلى قاعدة البيانات باستخدام مزود Eclipselink JPA؛
      • [oracle-config-jpa-openjpa] يقوم بتكوين طبقة JPA للوصول إلى قاعدة البيانات باستخدام مزود OpenJPA JPA؛
  • في [6]، يحتوي المجلد [eclipse config / launch configurations] على تكوينات التشغيل التي يمكن للقارئ استيرادها إلى Eclipse ثم تكييفها مع بيئته الخاصة؛
  • في [7]، يحتوي المجلد [spring-database-generic] على جميع أكواد الوصول إلى قاعدة البيانات المشتركة بين أنظمة إدارة قواعد البيانات الستة وموفري JPA الثلاثة؛
  • في [8]، يحتوي [spring-jdbc] على أربعة مشاريع توضح واجهة برمجة تطبيقات JDBC بالإضافة إلى Spring JDBC؛
  • في [9]، [spring-jpa / spring-jpa-generic] هو المشروع الذي يستخدم طبقة JPA للوصول إلى قاعدة البيانات. مشاريع [generic-create-db*] هي مشاريع JPA تُستخدم لإنشاء قواعد البيانات التي تستخدمها طبقة JPA؛
  • في [10]، يحتوي المجلد [spring-webjson] على المشاريع التي تعرض قاعدة البيانات على الويب؛

    • [spring-webjson-server-jdbc-generic] هي خدمة الويب التي تعرض قاعدة البيانات التي يتم الوصول إليها عبر Spring JDBC؛
    • [spring-webjson-server-jpa-generic] هي خدمة الويب التي تعرض قاعدة البيانات التي يتم الوصول إليها عبر Spring JPA؛
    • [spring-webjson-client-generic] هو العميل الوحيد الذي يسمح بالوصول إلى خدمتي الويب السابقتين؛
  • في [11]، يحتوي المجلد [spring-security] على المشاريع التي تعرض قاعدة البيانات على الويب مع وصول آمن؛

    • [spring-security-server-jdbc-generic] هي خدمة الويب الآمنة التي تعرض قاعدة البيانات التي يتم الوصول إليها عبر Spring JDBC؛
    • [spring-security-server-jpa-generic] هي خدمة الويب الآمنة التي تعرض قاعدة البيانات التي يتم الوصول إليها عبر Spring JPA؛
    • [spring-security-client-generic] هو العميل الوحيد الذي يسمح بالوصول إلى خدمتي الويب الآمنتين السابقتين؛
  • في [12]، يحتوي المجلد [spring-cors] على المشاريع التي تعرض قاعدة البيانات على الويب مع وصول آمن يسمح بالوصول عبر النطاقات، مثل ذلك الذي ينشأ من كود JavaScript للمتصفح؛

    • [spring-cors-server-jdbc-generic] هي خدمة الويب الآمنة التي تسمح بالوصول عبر النطاقات وتكشف قاعدة البيانات التي يتم الوصول إليها عبر Spring JDBC؛
    • [spring-cors-server-jpa-generic] هي خدمة الويب الآمنة التي تسمح بالوصول عبر النطاقات وتكشف عن قاعدة البيانات التي يتم الوصول إليها عبر Spring JPA؛
    • [spring-cors-client-generic] هو تطبيق ويب يستعلم عن خدمتي الويب السابقتين؛