Object-relational mapping

  • باستخدام نمط Repository Pattern في تطبيقي الذي يعتمد على Entity Framework 7، وجدت نفسي في حاجة إلى تحسين الطريقة التي يتم بها استرجاع البيانات من خلال الـ Repository Pattern، خاصةً في ما يتعلق بتحميل الكيانات بشكل فعّال باستخدام ThenInclude. يتمثل التحسين الذي أقوم به في توسيع طريقة GetById في الـ Repository الخاص بي، حتى تدعم تحميل الكيانات المتداخلة على مستويات أكثر من واحد. عند النظر إلى تنفيذ الطريقة، يمكن للمستخدم الآن استعمال ThenInclude لاسترجاع مستويات إضافية من الكيانات المتداخلة. لنلقي نظرة على التحديث الذي قمت به للطريقة GetById: csharp Copy code public virtual TEntity GetById ( int id, params Expression>[] paths ) { var result = this .Set.Include(paths.First()); foreach ( var path in paths.Skip( 1 )) { if (path.Body is MemberExpression) { result = result.ThenInclude(path); } else if (path.Body is MethodCallExpression methodCall && methodCall.Method.Name == Select ) { var innerPath = (MemberExpression)methodCall.Arguments[ 1 ]; result = result.ThenInclude(path).ThenInclude(innerPath); } } return result.FirstOrDefault(e => e.Id == id); } الآن يمكن استخدام ThenInclude لاسترجاع مستويات إضافية من الكيانات المتداخلة. على سبيل المثال، لاسترجاع الـ LineItems المرتبطة بكل Order يمكن القيام بذلك كما يلي: csharp Copy code productRepository.GetById( 2 , p => p.Orders.ThenInclude(o => o.LineItems), p => p.Parts); هذا التحسين يأتي لتلبية احتياجات تطبيقك وضمان فاعلية عملية تحميل البيانات من قاعدة البيانات باستخدام Entity Framework 7 وتقنيات Repository Pattern.

    الاقتران بين نمط Repository واستخدام Entity Framework 7 ليس فقط تحدٍ في بناء تطبيق فعّال ولكن أيضًا يتطلب فهماً عميقًا لكيفية تحميل البيانات بشكل فعّال. في تطبيقي، أقوم بتوسيع طريقة GetById في الـ Repository لدعم تحميل الكيانات بشكل مبكر باستخدام ThenInclude.

    لنبدأ بالتعديل على الكود الحالي:

    csharp
    public virtual TEntity GetById(int id, params Expressionobject>>[] paths) { var result = this.Set.Include(paths.First()); foreach (var path in paths.Skip(1)) { result = result.Include(path); } return result.FirstOrDefault(e => e.Id == id); }

    الآن، لدعم ThenInclude وتحميل الكيانات المتداخلة، يمكننا تحسين الكود كالتالي:

    csharp
    public virtual TEntity GetById(int id, params Expressionobject>>[] paths) { var result = this.Set.Include(paths.First()); foreach (var path in paths.Skip(1)) { if (path.Body is MemberExpression memberExpression) { result = result.ThenInclude(memberExpression); } else if (path.Body is MethodCallExpression methodCallExpression) { // Handle methods like Select, Where, etc. // You may need to customize this part based on your requirements. result = result.ThenInclude(methodCallExpression); } } return result.FirstOrDefault(e => e.Id == id); }

    الآن، يمكنك استخدام GetById بشكل مماثل للحصول على كيان مع تحميل كيانات متداخلة:

    csharp
    productRepository.GetById(2, p => p.Orders, p => p.Orders.ThenInclude(o => o.LineItems), p => p.Parts);

    هذا التعديل يمكن أن يسمح لك بتحميل الكيانات المتداخلة بشكل فعّال باستخدام ThenInclude في Entity Framework 7، مما يوفر لك قاعدة قوية لتوسيع تطبيقك بشكل أفضل وفقًا لاحتياجات متطلبات المشروع.

    المزيد من المعلومات

    باستخدام نمط Repository Pattern في تطبيقي الذ

  • حل مشكلة NullPointerException في Java: دليل تحسين البرنامج

    عند تحليل الشيفرة التي قدمتها، يظهر أن الخطأ الرئيسي يحدث في دالة addSwimmer() بسبب استخدام myList[maxIndex] قبل تهيئته بكائن جديد من الفئة Swimmer. لتجنب الخطأ، يجب إنشاء كائن جديد قبل تعيين القيم له. إليك التعديل الذي يمكنك تنفيذه:

    java
    public static void addSwimmer() { Scanner kbReader = new Scanner (System.in); // تحقق من أن هناك مكانًا فارغًا في المصفوفة قبل إضافة سباح جديد if (maxIndex < myList.length - 1) { maxIndex++; myList[maxIndex] = new Swimmer(); // إنشاء كائن جديد هنا System.out.println("What is the swimmer's name? "); String a = kbReader.nextLine(); myList[maxIndex].setName(a); // باقي الكود هنا... } else { System.out.println("Error: Cannot add more swimmers, the database is full."); } }

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

    بالنسبة إلى النقاط الأخرى:

    1. تأكد من تعريف gradeLevel في فئة Swimmer وتعيين قيمة لها إذا كان لديك نوايا لاستخدامها في المستقبل.

    2. في دالة showSwimmer(), ابتداءً من j=1 بدلاً من j=0 لتجنب عرض السباح الافتراضي في الموقع 0.

    3. لضمان أن لا يتم حفظ معلومات السباحين بشكل خاطئ في الملف، يفضل تنفيذ FileWriter() في نهاية البرنامج بعد الخروج من الحلقة الرئيسية.

    المزيد من المعلومات

    بالتأكيد، سأواصل تحليل الشيفرة وتقديم بعض النصائح والتحسينات:

    1. تحسين هيكلة الكود:

      • يمكنك فصل التعليمات الخاصة بإدخال البيانات في دالة addSwimmer() إلى دوال فرعية لتحسين قراءة الشيفرة وجعل الشيفرة أكثر وضوحًا.
      • قد تكون مناسبة لاستخدام تكنولوجيا الـ Object-Relational Mapping (ORM) لتبسيط عمليات التخزين والاسترجاع من قاعدة البيانات.
    2. تحسين إدارة الأخطاء:

      • يفضل إضافة التحقق من صحة الإدخالات، مثل التأكد من أن الاسم غير فارغ وأن القيم العددية إيجابية.
      • يمكنك استخدام معالجات الاستثناء للتعامل بشكل أفضل مع الأخطاء، مثل التعامل مع InputMismatchException عندما يدخل المستخدم نوع بيانات غير متوقع.
    3. تحسين إدارة الذاكرة:

      • يُفضل استخدام قائمة مرنة (ArrayList) بدلاً من مصفوفة ثابتة الحجم إذا كنت لا تعلم عدد السباحين المتوقع مسبقًا.
      • استخدام ArrayList سيسمح بتوسيع الحجم حسب الحاجة وتجنب حدوث أخطاء ArrayIndexOutOfBoundsException.
    4. تحسين واجهة المستخدم:

      • يمكنك إضافة رسائل توجيهية للمستخدم لجعل تفاعله مع البرنامج أكثر فهمًا.
      • استخدام دوال فرعية للمهام المكررة مثل قراءة البيانات من المستخدم.
    5. تحسين قراءة وكتابة الملف:

      • يفضل استخدام BufferedWriter مع FileWriter لتحسين أداء الكتابة إلى الملف.
      • يمكنك استخدام BufferedReader مع FileReader لتحسين أداء قراءة الملف.
    6. التعامل مع الإدخال:

      • يمكنك استخدام فئة java.util.InputMismatchException للتحقق من صحة إدخال المستخدم بدلاً من استخدام nextInt() دون التحقق.
    7. استخدام الأسلوب printf لتحسين الإخراج:

      • يمكنك استخدام System.out.printf للتحكم بشكل أفضل في تنسيق الإخراج، مما يجعل الناتج أكثر قراءة.

    هذه بعض التحسينات الممكنة. يمكنك تطبيق هذه الأفكار حسب احتياجاتك ومستوى التفاصيل الذي ترغب فيه في برنامجك.

  • تحويل البيانات في تطوير JSP: أفضل الممارسات والتقنيات

    في سياق تطوير تطبيقات الويب باستخدام تقنيات JSP (JavaServer Pages)، قد يطرأ على المطورين الحاجة إلى تحويل نص (String) إلى ResultSet أو قائمة (List) إلى ResultSet. يعتبر هذا التحويل أمرًا محوريًا في العديد من السيناريوهات، ولكن يجب فهم أن ResultSet يُستخدم بشكل رئيسي في تمثيل نتائج استعلام قاعدة البيانات.

    قد يكون من المتعب بعض الشيء تحويل String إلى ResultSet بشكل مباشر، نظرًا لأن ResultSet يُستخدم لتمثيل بيانات قاعدة البيانات المستردة. عمومًا، يمكن تنفيذ عمليات تحويل باستخدام مكتبات أو طرق مختلفة. على سبيل المثال، يمكن استخدام الكود التالي لتحويل String إلى ResultSet باستخدام Java:

    java
    String myString = "أي نص هنا"; ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(myString.getBytes()); ResultSet resultSet = null; try { // يتم استخدام PreparedStatement لتجنب هجمات حقن SQL PreparedStatement preparedStatement = connection.prepareStatement("SELECT ? AS my_column"); preparedStatement.setBinaryStream(1, byteArrayInputStream); // تنفيذ الاستعلام والحصول على ResultSet resultSet = preparedStatement.executeQuery(); } catch (SQLException e) { e.printStackTrace(); } // الآن لديك ResultSet يحتوي على البيانات من النص الأصلي

    أما بالنسبة لتحويل List إلى ResultSet، فمن الأسهل استخدام القائمة مباشرة في تحديث الواجهة الرسومية لتقديم البيانات للمستخدم. ومع ذلك، إذا كان هناك حاجة ضرورية لتحويلها إلى ResultSet، يمكنك استخدام تقنيات مختلفة مثل تكوين PreparedStatement مع Batch وتنفيذها بشكل دفعي.

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

    المزيد من المعلومات

    في سياق تطوير تطبيقات الويب باستخدام JavaServer Pages (JSP)، يعد تحويل البيانات بين أنواع مختلفة من الكائنات أمرًا شائعًا وهامًا. يمكن أن يتطلب ذلك مهارات معينة وفهمًا عميقًا لعمليات التعبير عن البيانات واستخدامها في سياق تطوير الواجهة الرسومية.

    1. استخدام PreparedStatement:
      يُفضل دائمًا استخدام PreparedStatement عند التعامل مع تحويل البيانات إلى ResultSet، حيث يقوم بتحسين أمان التطبيق عن طريق تجنب هجمات حقن SQL. يمكن استخدامه أيضًا لتحويل البيانات من String إلى ResultSet كما تم ذكره في الإجابة السابقة.

    2. استخدام ORM (Object-Relational Mapping):
      ORM هي تقنية تسهل تحويل البيانات بين الكائنات في البرنامج والجداول في قاعدة البيانات. مثل Hibernate أو JPA (Java Persistence API)، يمكن استخدامها لتسهيل وتبسيط تحويل البيانات بشكل أكثر فاعلية.

    3. استخدام تقنيات الربط البيني (Data Binding):
      في بعض الأحيان، يمكن استخدام تقنيات الربط البيني لتلقي البيانات مباشرة من الواجهة الرسومية (UI) وتحويلها إلى الهيكل البياني المناسب. يمكن أن تدعم بعض إطارات العمل (Framework) مثل Spring Data Binding هذه العمليات.

    4. استخدام تقنيات تحويل البيانات:
      يمكن استخدام تقنيات التحويل المتقدمة مثل Jackson أو Gson لتحويل بيانات JSON إلى كائنات Java، وبالعكس. يساعد ذلك في التفاعل بسلاسة مع بيانات الواجهة الرسومية والخوادم.

    5. تفادي تحويل البيانات عندما لا يكون ذلك ضروريًا:
      في بعض الحالات، يمكن أن يكون تحويل البيانات غير ضروري، خاصة إذا كان بإمكانك استخدام البيانات مباشرة دون الحاجة إلى تحويلها إلى هياكل بيانات أخرى.

    في النهاية، يتوقف اختيار كيفية تحويل البيانات على متطلبات التطبيق الخاص بك والحالة السياقية. يجب على المطور أن يكون على دراية بأدوات Java ومكتباتها المتاحة لتسهيل هذه العمليات وضمان كفاءة التطبيق وأمانه.

  • استكشاف قوة SQLAlchemy في تكامل بايثون مع قواعد البيانات

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

    مكتبة SQLAlchemy هي عبارة عن أداة قاعدية بيانات تُستخدم لتسهيل التفاعل مع قواعد البيانات باستخدام لغة بايثون. تتيح للمطورين إجراء عمليات قاعدية بيانات معقدة بطريقة بسيطة ومرنة. تعتمد SQLAlchemy على مفهوم ORM (Object-Relational Mapping) الذي يسمح بتمثيل الكائنات في اللغة البرمجية ككائنات في قاعدة البيانات.

    عند البدء في استخدام SQLAlchemy، يجب عليك تثبيتها أولاً باستخدام مدير الحزم في بايثون، على سبيل المثال:

    bash
    pip install sqlalchemy

    بمجرد تثبيت SQLAlchemy، يمكنك بدء استخدامها في تفعيل التفاعل بين تطبيقك وقاعدة البيانات. يبدأ الأمر بتحديد نموذج الكائنات الذي يتناسب مع هيكل قاعدة البيانات الخاصة بك. يمكنك استخدام فئات Python لتمثيل الجداول والعلاقات بينها.

    فيما يلي مثال بسيط يوضح كيفية استخدام SQLAlchemy لإنشاء نموذج بسيط:

    python
    from sqlalchemy import create_engine, Column, Integer, String, Sequence from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(Integer, Sequence('user_id_seq'), primary_key=True) name = Column(String(50)) age = Column(Integer) # انشاء محرك قاعدة البيانات engine = create_engine('sqlite:///:memory:') # إنشاء الجدول Base.metadata.create_all(engine)

    في هذا المثال، تم إنشاء فئة User التي تعبر عن جدول المستخدمين في قاعدة البيانات. يمكنك تخصيص هذا النموذج حسب احتياجات تطبيقك.

    بعد تحديد نموذج الكائنات، يمكنك بسهولة استخدام SQLAlchemy لإجراء عمليات متنوعة مثل الإضافة، والاستعلام، والتحديث، والحذف. يتيح لك ORM ترجمة العمليات بسلاسة بين لغة بايثون وقاعدة البيانات بدون الحاجة إلى الكثير من الكود.

    تجسد مكتبة SQLAlchemy فعالية وقوة في التفاعل مع قواعد البيانات، وهي تسهل على المطورين التركيز على تصميم التطبيق وتطويره دون الحاجة إلى التفكير الكثير في التفاصيل الدقيقة للتفاعل مع قاعدة البيانات.

    المزيد من المعلومات

    مكتبة SQLAlchemy تتميز بالعديد من الميزات والإمكانيات التي تسهل على المطورين إدارة وتفاعل تطبيقاتهم مع قواعد البيانات. سأستمر في توضيح بعض المفاهيم الرئيسية والميزات البارزة لهذه المكتبة.

    1. مفهوم ORM (Object-Relational Mapping):
      SQLAlchemy تعتمد على مفهوم ORM الذي يسمح للمطورين بتمثيل الكائنات في لغة البرمجة (مثل Python) ككائنات في قاعدة البيانات. هذا يعني أنك تستخدم فئات Python لتعريف الجداول والعلاقات في قاعدة البيانات، مما يجعل التفاعل مع البيانات أكثر سلاسة.

    2. التحقق من البيانات (Data Validation):
      SQLAlchemy توفر وسائل لتحقق البيانات المدخلة لضمان تناسقها وصحتها. يمكنك تحديد قواعد التحقق لحقول الجداول، مما يقلل من احتمالية حدوث أخطاء في إدخال البيانات.

    3. الاستعلامات المرنة (Flexible Queries):
      يمكنك بسهولة إجراء استعلامات مرنة باستخدام SQLAlchemy. يوفر الاستعلام اللغوي (Query DSL) وسيلة برمجية لبناء استعلامات قواعد البيانات بطريقة برمجية دون الحاجة إلى كتابة SQL يدويًا.

    4. دعم لمحركات قواعد البيانات المتنوعة:
      SQLAlchemy تدعم مجموعة واسعة من محركات قواعد البيانات، مما يسمح للمطورين باختيار المحرك الذي يناسب احتياجاتهم. يمكنك استخدامها مع قواعد البيانات الشائعة مثل PostgreSQL، MySQL، SQLite، وغيرها.

    5. التفاعل المتقدم مع العلاقات:
      تسمح SQLAlchemy بتعريف وإدارة العلاقات بين الجداول بشكل مباشر، مما يسهل على المطورين العمل مع بنية البيانات المعقدة التي تتضمن علاقات.

    6. دعم الهجرة (Migration Support):
      توفر SQLAlchemy أدوات لإدارة عمليات الهجرة، مما يسمح لك بتحديث هيكل قاعدة البيانات بسهولة دون فقدان البيانات أو التأثير على التطبيق.

    7. دعم للعمليات الجماعية (Bulk Operations):
      يمكنك استخدام SQLAlchemy لتنفيذ عمليات جماعية بفعالية، مثل إدراج عدة سجلات في وقت واحد، مما يحسن أداء التطبيق في حالات العمليات الكبيرة.

    في الختام، تُعد SQLAlchemy أداة قوية ومرنة للتفاعل مع قواعد البيانات في لغة بايثون. استفادة المطورين من ميزاتها تساهم في بناء تطبيقات فعّالة وسلسة التفاعل مع البيانات، مما يسهم في تحسين تجربة المستخدم وتسريع عمليات التطوير.

  • (Object-relational mapping) ORM ما هو الـ

    انت كمبرمج راح تشتغل الكثير من المشاريع التي تتمحور حول ادارة قاعدة البيانات يعني راح تسوي انظمة تخزن  بيانات بقاعدة البيانات بعدد من الجداول الي يكون بينها علاقات .

    بهاي الحالة راح تبدي تصمم قاعدة البيانات وتسوي العلاقات بين الجداول وهكذا امور , وهذا الشي راح يطلب منك خبره بكود الـSQL .
    بالاضافة الى تنفيذ الاستعلامات (Query) على قاعدة البيانات واستلام النتائج وهذا ايضا يطلب خبره بكود الـSQL .

    لو ربطت تطبيقك بقاعدة بيانات وتريد تنفيذ استعلامات على هذه القاعدة لازم تسوي كونكشن مع قاعدة البيانات وتمرر بكل مره استعلام معين حتى تحصل نتائج , ولو ردت تفلتر البيانات راح تمرر استعلام طويل ومعقد راح يكون بالنسبه الك اذا كنت قليل خبره بقاعدة البيانات .

    Object Relational Mapping. Simplify Your Life with ORM | by Erica M | Medium

    الـORM هوه عبارة عن كلاس يساعدك بالتعامل مع قاعدة البيانات بشكل اسهل وما راح يطلب منك خبره كبيره بالـSQL حتى تنفذ استعلامات لانه  راح يكون كله عباره عن مجموعة دوال تستدعيهن حتى تحصل النتيجة المناسبة مع امكانيه فلترة البيانات بشكل افضل  وايضا ترتيب البيانت على شكل Collection مناسب وسهل الاستخدام .

    طريقه استخدام الـORM هو تعمل كلاس بشكل معين وتخلي يورث كلاس الـORM بهذه الحاله صار عدك شي اسمه MODEL لكل جدول تسوي MODEL وراح تتعامل مع هذا المودل عن طريق عمل انستانس (object) من هذا الموديل واستدعاء الدوال المناسبه لعملك
    #مثال :- بلغة PHP بفريمورك الـLaravel اكو ORM اسمه Eloquent

    الكود بدون orm راح تحتاج بي 5 دوال تنفذهن مع كل استعلام ما عدا استعلام ادخال البيانات تنفذ 3 فقط
    mysqli_connect
    mysqli_query
    mysqli_fetch_XXX
    mysqli_free_result
    mysqli_close

    لكن لو استخدمت الـORM
    راح تسوي مودل باسم الجدول مثلا Student وفقط تستدعي
    () Student::all
    هذا راح يجيبلك كل السجلات من الجدول بكل بساطة .

    طبعا اكو الكثير من انواع الORM بكل لغه مثلا بالـJAVA تستخدم الـ repository وهو ايضا يعتمد على الـOOP مثل ما بالـEloquent .

    ببساطة الموضوع اذا كنت تريد تتعامل مع قاعدة بيانات بشكل سهل وسلس ابحث عن موضوع الـORM باللغة الي انت بتستخدمها .

زر الذهاب إلى الأعلى
إغلاق

أنت تستخدم إضافة Adblock

يرجى تعطيل مانع الإعلانات حيث أن موقعنا غير مزعج ولا بأس من عرض الأعلانات لك فهي تعتبر كمصدر دخل لنا و دعم مقدم منك لنا لنستمر في تقديم المحتوى المناسب و المفيد لك فلا تبخل بدعمنا عزيزي الزائر