for - Java-تخزين عبارات SQL في ملف خارجي




select in java jdbc (8)

أنا أبحث عن مكتبة جافا / إطار / تقنية تخزين عبارات SQL في ملف خارجي. يجب أن يكون فريق الدعم (بما في ذلك DBAs) قادراً على تغيير (قليلاً) العبارة للحفاظ عليها متزامنة في حالة تغييرات مخطط قاعدة البيانات أو لأغراض توليف.

فيما يلي المتطلبات:

  • يجب أن يكون الملف قابلاً للقراءة من تطبيق Java ولكن يجب أن يكون قابلاً للتعديل بواسطة فريق الدعم دون الحاجة إلى برامج تحرير رائعة
  • من الناحية المثالية ، يجب أن يكون الملف بتنسيق نص عادي ولكن XML على ما يرام أيضًا
  • السماح بتخزين / استرداد DML بالإضافة إلى عبارات DDL
  • يمكن إضافة عبارات جديدة في مرحلة لاحقة (التطبيق مرن بما فيه الكفاية لالتقاطها وتنفيذها)
  • يمكن تجميع البيانات (وتنفيذها كمجموعة من خلال التطبيق)
  • البيانات يجب أن تسمح للمعلمات

ملاحظات:

  • بمجرد استرجاع البيانات ، سيتم تنفيذها باستخدام JDBCT
  • لن يتم استخدام حاوية IOC الخاصة بالسبت أو Spring

حتى الآن ، تمكنت من العثور على مكتبات Java التالية ، والتي تستخدم الملفات الخارجية لتخزين عبارات SQL. ومع ذلك ، فأنا مهتم بشكل أساسي بالتخزين وليس بالمكتبة التي تخفي "تعقيدات" JDBC.

  • أكسامول مكتبة SQL

    عينة من محتوى الملف:

    <s:query name="get_emp">
      <s:param name="name" type="string"/>
      <s:sql databases="oracle">
        select    *
        from      scott.emp
                  join scott.dept on (emp.deptno = dept.deptno)
        where     emp.ename = <s:bind param="name"/>
      </s:sql>
    </s:query>
    
  • iBATIS

    عينة من محتوى الملف:

    <sqlMap namespace="Contact"">
        <typeAlias alias="contact"
            type="com.sample.contact.Contact"/">
        <select id="getContact"
            parameterClass="int" resultClass="contact"">
                select CONTACTID as contactId,
                       FIRSTNAME as firstName,
                       LASTNAME as lastName from
                       ADMINISTRATOR.CONTACT where CONTACTID = #id#
        </select>
    </sqlMap>
    <insert id="insertContact" parameterClass="contact">
    INSERT INTO ADMINISTRATOR.CONTACT( CONTACTID,FIRSTNAME,LASTNAME)
            VALUES(#contactId#,#firstName#,#lastName#);
     </insert>
    <update id="updateContact" parameterClass="contact">
    update ADMINISTRATOR.CONTACT SET
    FIRSTNAME=#firstName# ,
    LASTNAME=#lastName#
    where contactid=#contactId#
    </update>
    <delete id="deleteContact" parameterClass="int">
    DELETE FROM ADMINISTRATOR.CONTACT WHERE CONTACTID=#contactId#
    </delete>
    
  • WEB4J

    -- This is a comment 
     ADD_MESSAGE   {
     INSERT INTO MyMessage -- another comment
      (LoginName, Body, CreationDate)
      -- another comment
      VALUES (?,?,?)
     }
    
    -- Example of referring to a constant defined above.
    FETCH_RECENT_MESSAGES {
     SELECT 
     LoginName, Body, CreationDate 
     FROM MyMessage 
     ORDER BY Id DESC LIMIT ${num_messages_to_view}
    }
    

هل يمكن لأي شخص أن يوصي بحل يتم تجربته واختباره؟

https://code.i-harness.com


إذا كان يجب عليك القيام بذلك ، يجب أن تنظر في مشروع MyBatis . أنا لم أستعملها ، ولكن سمعت أنها أوصت عدة مرات.

لا يعتبر فصل SQL و Java النهج المفضل لدي ، لأن SQL هي في الواقع رمز ، وقارنته بشدة إلى رمز جافا الذي يطلق عليه. يمكن أن يكون الحفاظ على التعليمات البرمجية المنفصلة وتصحيحها أمرًا صعبًا.

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


انها بسيطة وموثوق بها لاستخدام الطبقات من الربيع. خذ ملفات SQL الخاصة بك وحفظها في بعض المواقع على classpath الخاص بك. يمكن أن يكون هذا في ملف JAR الذي يحتوي على SQL فقط إذا كنت تريد. ثم استخدم ClassPathResource في Spring لتحميل الملف إلى دفق واستخدام Apache IOUtils لتحويله إلى سلسلة. يمكنك بعد ذلك تنفيذ SQL باستخدام SimpleJdbcTemplate ، أو رمز DB الذي تختاره.

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


سأشجعك بشدة على استخدام الإجراءات المخزنة. هذا النوع من الأشياء هو بالضبط ما هم.


قم فقط بإنشاء ملف Java Properties بسيط باستخدام أزواج Key-value مثل هذا:

users.select.all = select * from user

قم بتعريف حقل خاص من نوع خصائص في فئة DAO الخاص بك وحقنه باستخدام تكوين فصل الربيع الذي سيقرأ القيم من الملف.

تحديث : إذا كنت تريد دعم عبارات SQL في أسطر متعددة ، استخدم هذا الترميز:

users.select.all.0 = select *
users.select.all.1 = from   user

لصق هنا answer على طريقة نظيفة للخارج طويلة (+20 خطوط SQL) عند استخدام jdbc الربيع؟ :

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

selectSomething: >
  SELECT column1, column2 FROM SOMETHING

insertSomething: >
  INSERT INTO SOMETHING(column1, column2)
  VALUES(1, '1')

هنا ، selectSomething و insertSomething هي أسماء استعلامات. لذلك من الملائم حقًا ويحتوي على عدد قليل جدًا من الأحرف الخاصة. يتم فصل الاستعلامات بخطوط فارغة ، ويجب وضع مسافة بادئة لكل نص استعلام. لاحظ أن طلبات البحث يمكن أن تحتوي تمامًا على المسافة البادئة الخاصة بهم ، بحيث يكون ما يلي صالحًا تمامًا:

anotherSelect: <
  SELECT column1 FROM SOMETHING
  WHERE column2 IN (
    SELECT * FROM SOMETHING_ELSE
  )

يمكنك بعد ذلك قراءة محتويات الملف إلى خريطة تجزئة بمساعدة مكتبة SnakeYAML ، باستخدام الكود أدناه:

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.FileUtils;
import java.io.FileReader;

import org.yaml.snakeyaml.Yaml;
import java.io.File;
import java.io.FileNotFoundException;

public class SQLReader {
  private Map<String, Map> sqlQueries = new HashMap<String, Map>();

  private SQLReader() {
    try {
      final File sqlYmlDir = new File("dir_with_yml_files");
      Collection<File> ymlFiles = FileUtils.listFiles(sqlYmlDir, new String[]{"yml"}, false);
      for (File f : ymlFiles) {
        final String fileName = FilenameUtils.getBaseName(f.getName());
        Map ymlQueries = (Map)new Yaml().load(new FileReader(f));
        sqlQueries.put(fileName, ymlQueries);
      }
    }
    catch (FileNotFoundException ex) {
      System.out.println("File not found!!!");
    }
  }
}

في المثال أعلاه ، يتم إنشاء خريطة الخرائط ، تعيين كل ملف YAML إلى خريطة تحتوي على أسماء / سلاسل طلبات بحث.


يمكنك أيضًا استخدام فئة QueryLoader في Apache Commons DbUtils ، والتي ستقرأ SQL من ملف خصائص. ومع ذلك ، سيكون عليك استخدام DbUtils أي نوع من يخدم نفس الغرض مثل JDBCT.


يمكنك استخدام السرعة لجعل قوالب SQL "scriptable" التي يمكنك استخدامها للعمل مع الملفات بطريقة مرنة. لديك عبارات بدائية مثل الشرطية والحلقات لبناء الأوامر sql الخاص بك.

لكنني أقترح بشدة استخدام البيانات المعدة و / أو الإجراءات المخزنة. بناء SQL الخاص بك بالطريقة التي تخطط بها سيجعلك عرضة لحقن SQL ، لن يتمكن خادم DB من تخزين استعلامات SQL (التي ستؤدي إلى أداء سيء).

راجع للشغل: يمكنك تخزين تعريف البيانات المعدة في الملفات أيضا. هذا ليس هو الحل الأفضل ولكن قريب جدا منه ، ويمكنك الحصول على الاستفادة من حماية وأداء SQL-injection.

عندما لا يتم إنشاء مخطط SQL للعمل مع عبارات معدّة أو إجراءات مخزنة ، قد تحتاج إلى إعادة التفكير في مخططك. ربما تحتاج إلى إعادة بناء.


يمكنك استخدام مرافق الترجمة للقيام بذلك. ثم استخدم اسم قاعدة البيانات مثل الإعدادات المحلية للحصول على إصدار "oraclish" من "insert-foo-in-bar" بدلاً من الإصدار الإنجليزي أو الفرنسي.

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





sql