كيف
تستخدم منشئ الاستعلامات Query builder للتخاطب مع
قاعدة البيانات في Laravel
يأتي
Laravel بإطار العمل مضمّنا مبدئيا؛ وهو ما يتيح بناء نماذج تُعالّج فيها
البيانات وتُطبّق عليها القواعد التي تحكُم سير التطبيق. يُيسّر Eloquent كثيرا من الأمور على المطوِّر؛ إلا أنّه يمكن أن يكون أحيانا غير مناسب لتعقيد المشروع الذي تعمل عليه. يوفّر
Laravel آلية للتعامل مع قواعد
البيانات مباشرة دون الحاجة لربط كائنات التطبيق بجداول
قاعدة البيانات. تُسمى هذه الآلية
منشئ الاستعلامات Query builder. كانت
الاستعلامات المعدّة بمنشئ
الاستعلامات ترجع النتائج، في الإصدارات السابقة (قبل الإصدار 5.3) من Laravel، على هيئة مصفوفة Array؛ إلا أن الأمر تغيّر في الإصدار 5.3 وأصبحت أغلب دوالّ بناء
الاستعلامات ترجع نتيجة من نوع Collection (مجموعة).
2.png
سنرى في هذا المقال أمثلة تفصيلية حول هذا التغيير، ولكن قبل ذلك سنعرّج على مقارنة بين Eloquent ومنشئ
الاستعلامات ومتى يكون استخدام أحدهما أنسب.
أيهما أستخدم.. Eloquent أم
منشئ الاستعلامات؟
يخضع تطوير البرمجيّات لإكراهات كثيرة، وهو ما يعني أن عليك أحيانا كتابة استعلامات SQL
للتخاطب مع
قاعدة البيانات مباشرة. يتيح Eloquent آلية أنيقة للتعامل مع
قاعدة البيانات بربطها بأصناف التطبيق ممّا يقلّل كثيرا من الحاجة لتدخّل المطوّر في تفاصيل تنفيذ العمليّات. تشمل التسهيلات التي يتيحها Eloquent:
التحقق المُستَتِر Dirty check: تحديث الحقول التي تغيّرت قيمتها فقط دون غيرها، عند تنفيذ استعلامات UPDATE.
ربط النماذج بأحداث Events؛ مثلا لإشعار المستخدمين أو تحديث إحصائيات عند إنشاء مستخدم جديد.
إدارة الحذف اللطيف Soft delete: تعليم تسجيلة على أنها محذوفة بدلا من حذفها فعلا.
تنفيذ آليات التحميل الحثيث Lazy loading (طلب
البيانات عند الحاجة إليها).
يمكن - بالطبع - تطبيق هذه الآليات بنفسك دون الاعتماد على Eloquent؛ إلا أن ذلك سيأخذ وقتا. من الجيد أن يكون لديك سبب مقنع للوقت الذي ستمضيه في هذه المهمة بدلا من التركيز على أمور *قد* تكون أهم. سيكون مثاليّا جدا الحصولُ على كلّ هذه التسجيلات بدون دفع ثمن، إلا أن الأمور في الواقع ليست مثالية. الثمن الذي تدفعه مقابل التسهيلات التي يتضمّنها Eloquent - وأطر عمل ORM الأخرى، بغضّ النظر عن لغة البرمجة - هو سرعة تنفيذ الاستعلامات. على الجهة الأخرى، تمكّن كتابة
الاستعلامات من الوصول إلى أقصى سرعة ممكنة في التنفيذ، مقابل التضحية بالجهد والوقت أثناء التطوير.
لا يوجد مانع من مزج جميع الوسائل المتاحة أمامك؛ بل إن الأمر محبّذ. مثلا؛ استخدم Eloquent عندما تتعامل مع كيانات منفردة (استمارة تسجيل على موقع مثلا)، الجأ لمنشئ
الاستعلامات في المهامّ التي تتطلب وقتا للتنفيذ (كيانات بالجملة Batch processing أو إعداد تقارير على سبيل المثال) واكتب استعلامات SQL مباشرة عندما تكون أمام استعلام شديد التعقيد.
الجديد في
Laravel 5.3
نستخدم
منشئ الاستعلامات في المثال التالي للحصول على كافة المستخدمين (جدول users في
قاعدة البيانات):
DB::table('users')->get();
تكافئ التعليمة السابقة في نتيجتها تنفيذ الاستعلام التالي:
SELECT * FROM users;
كانت النتيجة، في الإصدارات السابقة من Laravel، من نوع Array (مصفوفة)؛ إلا أن هذا الأمر تغيّر في الإصدار 5.3 لتصبح النتيجة من نوع Collection (مجموعة). يعني هذا أنه للوصول إلى العنصر الأول في مجموعة المستخدمين السابقة فإننا يمكن أن نكتب:
DB::table('users')->get()->first();
بدلا من:
DB::table('users')->get()[0];
يجعل هذا التغيير من
منشئ الاستعلامات متناسقا في نوع النتيجة مع Eloquent الذي يرجع مجموعة كائنات؛ كما أنه يمكّن من استخدام الدوال الموجودة مبدئيا للتعامل مع المجموعات؛ ومن بينها الدالة all التي ترجع مصفوفة مكافئة للمجموعة؛ مثلا ترجع التعليمة التالية مصفوفة بالمستخدمين:
DB::table('users')->get()->all();
إن كان لديك تطبيق مبني على اعتبار أن
منشئ الاستعلامات يُرجع النتائج على هيئة مصفوفات، فأسهل طريقة لتعديل الشفرة المصدرية للتوافق مع تغيير نوع النتيجة إلى مجموعة بدلا من مصفوفة؛ هي استخدام الدالة all.
ملحوظة 1: لا ينطبق التغيير المذكور أعلاه (إرجاع مجموعة بدلا من مصفوفة) على دوال الصنف DB التي تتعامل مع استعلامات SQL مباشرة. مثلا؛ ترجع التعليمة التالية مصفوفة:
DB::select('SELECT name FROM users WHERE id = ?', [1]);
ملحوظة 2: انتبه عند استخدام استعلامات SQL مباشرة من ثغرات الحَقن SQL injection. استخدم ربط المتغيّرات Binding (كما في الملحوظة 1) بدلا من تمرير المتغيّر مباشرة كما في الاستعلام التالي:
DB::select("SELECT name FROM users WHERE id = '$id' "]);
قد يمثل الاستعلام الأخير خطرا إن لم يُتحقّق من المتغيّرid$ قبل استخدامه في الاستعلام. يتحقّق
Laravel تلقائيا من المُدخلات عند ربط المتغيّرات كما في استعلام الملحوظة 1.