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




6 Answers

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

users.select.all = select * from user

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

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

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

أنا أبحث عن مكتبة جافا / إطار / تقنية تخزين عبارات 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}
    }
    

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




كان الحل البسيط الذي قمنا بتنفيذه عند مواجهة هذا هو إخراج SQL / DML إلى ملف (mySql.properties) ، ثم استخدام MessageFormat.format (String [] args) لحقن الخصائص الديناميكية في SQL.

على سبيل المثال: mySql.properties:

select    *
    from      scott.emp
              join scott.dept on (emp.deptno = dept.deptno)
    where     emp.ename = {0}

طرق المساعدة:

public static String format(String template, Object[] args) {
    String cleanedTemplate = replaceSingleQuotes(template);
    MessageFormat mf = new MessageFormat(cleanedTemplate);
    String output = mf.format(args);
    return output;
}
private static String replaceSingleQuotes(String template) {
    String cleaned = template.replace("'", "''");
    return cleaned;
}

ثم استخدمه على النحو التالي:

String sqlString = youStringReaderImpl("/path/to/file");
String parsedSql = format(sqlString, new String[] {"bob"});



توفر مكتبة ElSql هذه الوظيفة.

يتكون ElSql من ملف جرة صغير (ست طبقات عامة) يسمح بتحميل ملف SQL خارجي (elsql). يستخدم الملف تنسيقًا بسيطًا لتوفير سلوك أكثر بعض الشيء من مجرد تحميل ملف:

-- an example comment
@NAME(SelectBlogs)
  @PAGING(:paging_offset,:paging_fetch)
    SELECT @INCLUDE(CommonFields)
    FROM blogs
    WHERE id = :id
      @AND(:date)
        date > :date
      @AND(:active)
        active = :active
    ORDER BY title, author
@NAME(CommonFields)
  title, author, content

// Java code:
bundle.getSql("SelectBlogs", searchArgs);

يتم تقسيم الملف إلى كتل @NAME والتي يمكن الإشارة إليها من الشفرة. يتم تعريف كل كتلة بمسافة بادئة بيضاء كبيرة. @PAGING الشفرة الضرورية @PAGING مثل FETCH / OFFSET. سيتم إخراج @AND فقط إذا كان المتغير المحدد موجودًا (يساعد في إنشاء عمليات بحث ديناميكية). يعالج DSL أيضًا LIKE vs = for wildcards في عمليات البحث. الهدف من علامات DSL الاختيارية هو توفير الأساسيات الشائعة التي غالباً ما تحدث عند محاولة إنشاء SQL ديناميكية بطريقة محايدة لقاعدة البيانات.

مزيد من المعلومات على blog أو دليل المستخدم .




لصق هنا 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 إلى خريطة تحتوي على أسماء / سلاسل طلبات بحث.




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

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




dynamic-query هو إطار مفتوح المصدر جيد لأولئك الذين يريدون شيئا بين JDBC و ORM.

1 سهل SQL. - يحفظ SQL عادي إلى ملفات خارجية. لا توجد علامات مكررة ، يدعم التعليقات.

/* It also supports comment.
This code is in an external file 'sample.sql', Not inisde java code.*/
listUsers : select * from user_table
where user_id= $$;  /* $$ will automatically catch a parameter userId */


2 قابلة للتوسيع SQL. ، وهو يدعم المعلمات ، بما في ذلك الملفات الأخرى والاستعلام الفرعي.

listUsers:
select
    id, amount, created
    @checkEmail{ ,email } 
from user_table
where amount > $amt and balance < $amt
    @checkDate { and created = $$ }
    @checkEmail{ and email in (
        select email from vip_list ) } ;        
/* Above query can be four queries like below.
1. listUsers
2. listUsers.checkDate 
3. listUsers.checkEmail
4. listUsers.checkDate.checkEmail 
*/



-- It can include other files like below
& ../hr/additional hr.sql ; 
& ../fi/additional fi.sql ;


جافا رمز المثال باستخدام أعلاه. قيم الإعداد إلى ديسيبل.

QueryUtil qu = qm.createQueryUtil("selectAll");
try {
    qu.setConnection(conn);

    // with native jdbc
    qu.setString("alpha");
    qu.setDouble(10.1);
    qu.executeQuery();

    // or with bean
    qu.executeQuery(new User("alpha", 10.1));

    // or with map
    Map<String, Object> map=new HashMap<String, Object>();
    map.put("userName", "alpha");
    map.put("amt", 10.1);
    qu.executeQuery(map);

    // or with array
    qu.executeQueryParameters("alpha", 10.1);

جافا رمز المثال باستخدام أعلاه. الحصول على القيم من ديسيبل.

    while (qu.next()) // == qu.rs.next()
    {
        // native jdbc
        String usreName = qu.getString("user_name"); 
        double amt = qu.getDouble("amt");

        // or bean
        User user = new User();
        qu.updateBean(user);

        // or array
        Object[] values = qu.populateArray();
    }
} catch (Exception e) {
    e.printStackTrace();
} finally {
    qu.closeJust();
}



Related


Tags

java   jdbc   sql