Skip to content

1. مقدمه

نسخه PDF این سند در |ICI| موجود است.

نمونه‌های موجود در این سند در |ICI| در دسترس هستند.

1.1. Contenu

در این سند، هدف ما بررسی پیکربندی‌های مختلف عملیات پایگاه داده است. بیایید معماری لایه‌ای زیر را در نظر بگیریم:

جریان اجرا از چپ به راست است:

  • یکی از کلاس‌های لایه [ui] (رابط کاربری) ابتدا اجرا می‌شود. این کلاس لایه‌های [metier] و [dao] را نمونه‌سازی می‌کند. اگر لایه [ui] یک رابط کاربری گرافیکی باشد، در این صورت منتظر اقدامات کاربر می‌ماند. یک اقدام کاربر می‌تواند اجرای متدها را در تمام لایه‌های معماری، تا خود پایگاه داده، تحریک کند. نتیجه این اجراها به شکلی یا دیگری به کاربر ارائه می‌شود؛

نقش لایه‌های مختلف می‌تواند به شرح زیر باشد:

  • لایه [JDBC] (ارتباطات جاوا DataBase) یک رابط دسترسی جهانی به پایگاه داده است. این لایه همیشه همان رابط را به لایه [DAO] ارائه می‌دهد. اگر SGBD تغییر کند، کافی است درایور JDBC را تغییر داد. لایه [DAO] بدون تغییر باقی می‌ماند، مشروط بر اینکه تعدادی قاعده رعایت شده باشد. با این حال، تضمین ۱۰۰٪ قابلیت حمل بین نسخه‌های SGBD دشوار است، زیرا این نسخه‌ها اغلب حاوی بخش قابل توجهی از کد اختصاصی SQL هستند که نادیده گرفتن آن دشوار است، زیرا اغلب بهبودهای عملکردی را ارائه می‌دهد. به محض استفاده از SQL اختصاصی، قابلیت حمل به SGBD دیگر امکان‌پذیر نیست. علاوه بر این، پیاده‌سازی‌های SGBD اغلب سیاست‌های متفاوتی برای تولید خودکار کلیدهای اصلی دارند، با کلمات کلیدی که از یک پیاده‌سازی به پیاده‌سازی دیگر متفاوت است. با این وجود، در این سند ما موفق به انتقال معماری مورد مطالعه JDBC به شش نمونه مختلف SGBD شده‌ایم، با این پذیرش که برای هر یک از آنها یک پروژه پیکربندی جداگانه وجود دارد؛
  • لایه [DAO] یک رابط برای دسترسی به داده‌ها از پایگاه دادهٔ خاص مورد استفاده ارائه می‌دهد (که باید از رابط JDBC متمایز شود، رابطی که متدهای معتبر برای هر SGBD را ارائه می‌کند)؛
  • لایه [métier] قواعد مدیریتی یا قواعد کسب‌وکار برنامه را پیاده‌سازی می‌کند.
    • داده‌های ورودی آن شامل داده‌هایی از پایگاه داده از طریق لایه [dao] و/یا ورودی کاربر است که توسط لایه [ui] به آن ارسال می‌شود؛
    • این لایه داده‌هایی تولید می‌کند که می‌تواند آن‌ها را از طریق لایه [dao] در پایگاه داده ذخیره کند و/یا به لایه [ui] که از آن پرس‌وجو کرده است بازگرداند تا به کاربر نمایش داده شود؛
  • لایه [ui] لایه‌ای است که اقدامات کاربر را اجرا کرده و نتایج آن را به کاربر بازمی‌گرداند؛

در نمودار بالا، لایه [DAO] درخواست‌های SQL را برای اجرا در لایه [JDBC] ارسال می‌کند. در سال‌های اخیر (از سال ۲۰۰۶)، این معماری به شرح زیر تکامل یافته است:

اکنون لایه JPA (Java Persistence API) است که درخواست‌های SQL را به لایه JDBC ارسال می‌کند و نتایج را از آن دریافت می‌نماید. لایه [JPA] عملیات مربوط به پایدارسازی، تغییر، حذف و بازیابی اشیاء را به لایه [DAO] ارائه می‌دهد. لایه [DAO] دیگر دستورات SQL را صادر نمی‌کند. این رویکرد قابل حمل‌تر است زیرا پیاده‌سازی‌های JPA با تفاوت‌های بین SGBD کنار می‌آیند، اما کندتر از فناوری 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-serveur] را فراهم می‌کند. ما اطمینان حاصل خواهیم کرد که لایه‌های [DAO-Client] و [3]، رابط‌های [IDAO-serveur] و [1] را پیاده‌سازی کنند. این امر به ما امکان می‌دهد تا از همان تست [JUnitTestsDao] استفاده کنیم که قبلاً دو بار ([4]) استفاده شده است؛
  • در [3]، لایه [DAO-client] با استفاده از Spring RestTemplate پیاده‌سازی خواهد شد؛

پس از انجام این کار، دسترسی به سرویس وب را ایمن خواهیم کرد:

  • در [5]، درخواست کلاینت HTTP از یک لایه احراز هویت که با استفاده از Spring Security پیاده‌سازی شده است، عبور می‌کند؛

پس از انجام این کار، معماری قبلی را به شکل زیر توسعه خواهیم داد:

  • در [3]، خودِ برنامهٔ مشتری یک برنامهٔ وب است. این برنامه یک فرم ([5]) نمایش می‌دهد که امکان ارسال پرس‌وجو به URL سرویس وب امن را فراهم می‌کند. دسترسی به سرویس وب امن از طریق HTTP توسط لایه‌ای از [DAO-client-js] که به زبان جاوااسکریپت پیاده‌سازی شده است، تسهیل می‌شود. این معماری از آنچه درخواست‌های بین‌دامنه‌ای نامیده می‌شوند، استفاده می‌کند:
    • سرویس وب [2]، URL را در قالب [http://machine1:port1/] ارائه می‌دهد؛
    • برنامه وب کلاینت [3] از یک URL [http://machine2:port2/] دانلود می‌شود. اگر [http://machine2:port2/] با [http://machine1:port1/] (همان ماشین، همان پورت) یکسان نباشد، آنگاه مرورگر کلاینت درخواست‌های لایه [DAO-client-js] به HTTP را مسدود خواهد کرد. برای حل این مشکل، سرویس وب باید درخواست‌های بین‌دامنه‌ای را مجاز کند. خواهیم دید چگونه؛

پروژه‌های ارائه‌شده با شش نمونه زیر از SGBD آزمایش شده‌اند:

  • MySQL 5 نسخهٔ Community؛
  • SQL سرور ۲۰۱۴ اکسپرس؛
  • PostgreSQL 9.4;
  • Oracle Express 11g نسخهٔ ۲؛
  • IBM DB2 Express-C 10.5;
  • فایربرد 2.5.4;

برای هر یک از این SGBD، چهار لایهٔ مختلف [DAO] توسعه داده شده‌اند:

  • یک لایه پیاده‌سازی‌شده با Spring JDBC;
  • یک لایه پیاده‌سازی‌شده با Spring JPA و ارائه‌دهنده Hibernate JPA;
  • یک لایه پیاده‌سازی‌شده با Spring JPA و ارائه‌دهنده JPA EclipseLink؛
  • یک لایه پیاده‌سازی شده با Spring JPA و ارائه‌دهنده JPA OpenJPA;

بنابراین مجموعه‌ای از بیست‌وچهار پیکربندی مختلف ارائه می‌شود. تلاش زیادی برای فاکتورگیری صرف شده است:

  • بیشتر کدها تنها یک‌بار نوشته می‌شوند. این بر اساس دو پروژه پیکربندی Maven است:
    • یکی لایه JDBC را پیکربندی می‌کند؛
    • دیگری لایه JPA را پیکربندی می‌کند؛

پروژه پیکربندی Maven برای لایه JDBC [1] یک SGBD خاص شامل دو مرحله است:

  • وارد کردن آرشیو درایور JDBC;
  • تعریف اعتبارنامه‌های دسترسی برای پایگاه داده در حال استفاده و دستورات مختلف SQL که لایه [DAO1] به درایور JDBC ارسال خواهد کرد. اگرچه SQL استاندارد شده است، اما مشکلات قابل حمل بودن به وجود آمده است، عمدتاً به دلیل وجود نام‌های جدول و ستون در پرس‌وجوها که مشخص شد در برخی SGBD کلمات کلیدی ممنوعه هستند. (جدول ROLES برای DB2، ستون PASSWORD برای Firebird). علاوه بر این، اگرچه نام یک ستون معمولاً نسبت به حروف بزرگ و کوچک بی‌تفاوت است، ما با PostgreSQL در مورد ستون ID در کلید اصلی جدول‌ها مواجه شدیم. این سیستم اصرار داشت که نام آن باید به صورت حروف کوچک id باشد. این‌ها نمونه‌های رایجی از مشکلات غیرمنتظره قابلیت حمل هستند؛

سه پروژه پیکربندی Maven برای لایه‌های JPA و [2] یک SGBD خاص نیز شامل دو مرحله هستند:

  • وارد کردن آرشیو پیاده‌سازی JPA؛
  • پیکربندی پیاده‌سازی JPA که برای SGBD متصل‌شده‌ی خاص استفاده می‌شود. در واقع، لایه JPA است که دستورات SQL را به لایه JDBC ارسال می‌کند. برای عملکرد مؤثر، باید SGBD را بشناسد تا دستورات SQL را که آن تشخیص خواهد داد، برایش ارسال کند. این دستورات ممکن است از SQL که مالک این SGBD است، و همچنین ویژگی‌های خاص آن (انواع داده‌ها، توالی‌ها، تریگرها، رویه‌ها، تولید خودکار کلیدهای اصلی و غیره) استفاده کنند؛

بنابراین بیست و چهار پروژه پیکربندی Maven (۴ پیکربندی × ۶ SGBD) وجود دارد که تمام پروژه‌های عملیاتی پایگاه داده دیگر بر اساس آن‌ها خواهند بود. در نمودارهای بالا، از آنجایی که لایه‌های [DAO1] و [DAO2] رابط یکسانی را فراهم می‌کنند، ۲۴ پیکربندی دو معماری نشان داده شده در بالا با استفاده از یک کلاس تست واحد، [JUnitTestsDao]، آزمایش خواهند شد. پس از تأیید این معماری‌ها، هیچ مشکل دیگری وجود ندارد:

  • پروژه Maven برای انتشار پایگاه داده در وب بر این دو معماری مبتنی است. بنابراین در اینجا نیز ۲۴ پیکربندی ممکن وجود دارد؛
  • پروژه Maven برای ایمن‌سازی دسترسی به سرویس وب نیز بر پروژه قبلی بنا شده است و همچنین ۲۴ پیکربندی ممکن دارد؛
  • در نهایت، پروژه Maven که درخواست‌های بین‌دامنه‌ای به سرویس وب امن را امکان‌پذیر می‌سازد، بر پروژه قبلی بنا شده است و آن نیز ۲۴ پیکربندی ممکن دارد؛

این مطالعه با استفاده از SGBD، MySQL5 و پیاده‌سازی Hibernate با شناسه JPA انجام می‌شود. سپس کد را به پیاده‌سازی Eclipselink (JPA) و پیاده‌سازی OpenJPA منتقل کردیم. سپس کد را به سایر پایگاه‌های داده (PostgresQL، Oracle؛ SQL، Server؛ DB2، Firebird) منتقل می‌کنیم.

این دوره برای مبتدیان طراحی شده است. اکثر مفاهیم مورد استفاده توضیح داده شده‌اند. هیچ دانش قبلی از برنامه‌نویسی پایگاه داده یا برنامه‌نویسی وب مورد نیاز نیست. با این حال، درک عمیق زبان SQL ضروری است، زیرا پرس‌وجوهای SQL مورد استفاده توضیح داده نشده‌اند.

برای درک مثال‌ها، دانش پایه‌ای زبان جاوا لازم است که می‌توان آن را در هر دوره مقدماتی این زبان یافت. دو فصل اول سند [مقدمه‌ای بر زبان جاوا (۱۹۹۸)] کافی است. این سند قدیمی است (۱۹۹۸، بازنگری‌شده در ۲۰۰۲) اما اصول اولیه در آن موجود است. برای یک دوره جامع، می‌توان کتاب مفصل ژان-ماری دوودو با عنوان [http://www.jmdoudoux.fr/java] را مطالعه کرد.

این سند به هیچ وجه جامع نیست. هدف از آن صرفاً ارائه یک روش‌شناسی و قطعاتی از کد است که می‌توان در زمینه‌های مشابه از آنها استفاده مجدد کرد. این سند به گونه‌ای نوشته شده است که می‌توان آن را بدون در دست داشتن رایانه خواند. در نتیجه، شامل تصاویر صفحه متعدد است.

اگرچه این سند همه ویژگی‌های زبان جاوا یا تمام حوزه‌های کاربرد آن را پوشش نمی‌دهد، اما می‌توان از آن به عنوان یک منبع آموزشی برای این زبان استفاده کرد. با دنبال کردن این سند—حتی اگر به طور کامل نباشد—یک مبتدی به سطح «جاوای پیشرفته» هم در استفاده از زبان و هم در چارچوب اسپرینگ (Spring framework) خواهد رسید. سپس می‌توانند آموزش جاوا خود را با کتاب‌های زیر ادامه دهند:

1.2. Sources

این سند دو منبع اصلی دارد:

برای کسب اطلاعات بیشتر درباره Spring، می‌توانید از مراجع زیر استفاده کنید:

  • سند مرجع چارچوب Spring [http://docs.spring.io/spring/docs/current/spring-framework-reference/pdf/spring-framework-reference.pdf];
  • تعداد زیادی آموزش Spring را می‌توان در URL و [http://spring.io/guides] یافت؛
  • وب‌سایت [developpez.com] که به اسپرینگ اختصاص دارد [http://spring.developpez.com/];
  • آموزش [http://www.tutorialspoint.com/spring/spring_tutorial.pdf];

خوانندگانی که دانش کافی از SQL ندارند، می‌توانند اصول اولیه را از کتاب [Introduction au langage SQL avec le SGBD Firebird] در URL [http://tahe.developpez.com/divers/sql-firebird/] بیاموزند.

1.3. ابزارهای مورد استفاده

مثال‌های زیر در محیط زیر آزمایش شده‌اند:

  • ماشین ویندوز 8.1 پرو 64 بیتی؛
  • JDK 1.8 (بخش 23.1);
  • IDE Spring Tool Suite 3.6.3 (بخش 1);
  • مرورگر کروم (از سایر مرورگرها استفاده نشده است)؛
  • افزونه کروم [Advanced Rest Client] (بند 1);
  • SGBD MySQL نسخهٔ جامعهٔ ۵.۶ (بند ۲۳.۴);
  • SGBD SQL Server 2014 Express (بند 23.9);
  • SGBD PostgreSQL 9.4 (بند 23.7);
  • SGBD Oracle Express 11g Release 2 (بند 23.6);
  • SGBD IBM DB2 Express-C 10.5 (بند 23.8);
  • SGBD Firebird 2.5.4 (بخش 23.10);
  • مشتریان EMS برای شش SGBD خود (بند 23.5);

لطفاً به JDK نسخهٔ 1.8 توجه کنید. یکی از مطالعات موردی از روشی در بستهٔ [java.lang] در جاوا 8 استفاده می‌کند.

اکثر مثال‌ها پروژه‌های Maven هستند که می‌توان آن‌ها را با استفاده از Eclipse، IntellijIDEA یا NetBeans باز کرد. در ادامه، اسکرین‌شات‌ها از Spring Tool Suite، یک نسخه از Eclipse، گرفته شده‌اند.

1.4. مثال‌ها

این مثال‌ها در URL [http://tahe.developpez.com/java/spring-database] به صورت یک فایل قابل دانلود zip در دسترس هستند.

  • در [1]، پوشه‌های مثال؛
  • تا [2]؛ پوشه [spring-core] شامل پروژه‌های آموزشی Spring است؛
  • در [3]، پوشه [spring-database-config] شامل پروژه‌های پیکربندی JDBC و JPA برای شش پایگاه داده است؛
  • در [4]، پیکربندی پایگاه داده Oracle SGBD. این شامل سه پوشه است:
    • [databases] شامل اسکریپت‌های SQL برای ایجاد دو پایگاه داده مورد استفاده در سند است؛
    • [jdbc-driver] شامل درایور Oracle JDBC و همچنین یک اسکریپت برای نصب آن در مخزن محلی Maven است؛
    • [eclipse] شامل [5]، چهار پروژه پیکربندی Oracle است:
      • [oracle-config-jdbc] لایه دسترسی JDBC را برای SGBD پیکربندی می‌کند؛
      • [oracle-config-jpa-hibernate] لایه دسترسی JPA را برای SGBD با استفاده از ارائه‌دهنده Hibernate JPA پیکربندی می‌کند؛
      • [oracle-config-jpa-eclipselink] لایه دسترسی JPA را به SGBD با استفاده از ارائه‌دهنده Eclipselink JPA پیکربندی می‌کند؛
      • [oracle-config-jpa-openjpa] لایه دسترسی JPA را به SGBD با استفاده از ارائه‌دهنده JPA OpenJPA پیکربندی می‌کند؛
  • در [6]، پوشه [eclipse config / launch configurations] حاوی پیکربندی‌های زمان اجرا است که کاربر می‌تواند آن‌ها را به اکلپس وارد کرده و سپس متناسب با محیط خود سفارشی کند؛
  • در [7]، پوشه [spring-database-generic] حاوی تمام کدها برای دسترسی به SGBD است که برای شش فایل SGBD و سه ارائه‌دهنده JPA مشترک است؛
  • در [8]، [spring-jdbc] شامل چهار پروژه است که شامل API، 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] شامل پروژه‌هایی است که پایگاه داده را با دسترسی امن در وب ارائه می‌کنند و امکان دسترسی بین‌دامنه‌ای مانند دسترسی ناشی از کد جاوااسکریپت مرورگر را فراهم می‌آورند؛

    • [spring-cors-server-jdbc-generic] سرویس وب امنی است که دسترسی بین‌دامنه‌ای را فعال می‌کند و پایگاه داده‌ای را که از طریق Spring JDBC به آن دسترسی می‌شود، در معرض دید قرار می‌دهد؛
    • [spring-cors-server-jpa-generic] سرویس وب امنی است که دسترسی بین‌دامنه‌ای را امکان‌پذیر می‌سازد و پایگاه داده‌ای را که از طریق Spring JPA به آن دسترسی پیدا می‌شود، در معرض دید قرار می‌دهد؛
    • [spring-cors-client-generic] یک برنامه وب است که امکان ارسال پرس‌وجو به دو سرویس وب قبلی را فراهم می‌کند؛