46 votes

Java - Stockage d'instructions SQL dans un fichier externe

Je suis à la recherche d'une librairie Java/cadre/technique de stocker des instructions SQL dans un fichier externe. L'équipe de soutien (y compris les Administrateurs de base de données) doit être en mesure de modifier (légèrement) la déclaration pour les garder synchronisés dans le cas du schéma de la base des changements ou à des fins d'optimisation.

Voici les conditions:

  • Le fichier doit être lisible à partir d'un Java l'application, mais aussi doit être modifiable par l'équipe de soutien sans la nécessité des grands éditeurs
  • Idéalement, le fichier doit être dans la plaine format texte, mais le XML est OK aussi
  • Permettre DML ainsi que des instructions DDL pour être stockée / (extrait
  • De nouvelles déclarations peuvent être ajoutés à un stade ultérieur (l'application est assez flexible pour les ramasser et de les exécuter)
  • Les déclarations peuvent être regroupées (et exécuté en tant que groupe par l'application)
  • États doivent autoriser les paramètres

Notes:

  • Une fois extraites, les déclarations exécutée à l'aide du Printemps JDBCTemplate
  • Hibernate ou de Printemps du conteneur IOC ne sera pas utilisé

Jusqu'à présent, j'ai réussi à trouver la suite des bibliothèques Java, qui utilisent des fichiers externes pour stocker des instructions SQL. Cependant, je suis surtout intéressé par le stockage plutôt que d'une bibliothèque qui cache tous JDBC "complexités".

  • Axamol SQL Bibliothèque

    Exemple de contenu du fichier:

    <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

    Exemple de contenu du fichier:

    <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}
    }
    

Quelqu'un peut-il recommander une solution qui est essayé et testé?

58voto

Boris Pavlović Points 22207

Créez simplement un simple fichier de propriétés Java avec des paires clé-valeur comme celle-ci:

 users.select.all = select * from user
 

Déclarez un champ privé de type Propriétés dans votre classe DAO et injectez-le à l'aide de la configuration Spring, qui lira les valeurs du fichier.

UPDATE : si vous souhaitez prendre en charge des instructions SQL sur plusieurs lignes, utilisez cette notation:

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

8voto

John Stauffer Points 5988

Si vous devez le faire, vous devriez regarder la MyBatis projet. Je ne l'ai pas utilisé, mais nous avons entendu il a recommandé un certain nombre de fois.

La séparation SQL et Java n'est pas mon approche préférée, depuis SQL est en fait le code, et est étroitement associé à la Java le code qui l'appelle. Le maintien et le débogage de l'séparés code peut être difficile.

Absolument ne pas utilisées stockées procs pour cela. Ils devraient seulement être utilisés pour améliorer les performances en réduisant le trafic entre la DB et de la demande.

7voto

Rich Kroll Points 2524

Une solution simple que nous avons mise en œuvre face à cela consistait à externaliser SQL / DML dans un fichier (mySql.properties), puis à utiliser MessageFormat.format (String [] args) pour injecter des propriétés dynamiques dans le code SQL.

Par exemple: mySql.properties:

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

Méthodes d'utilité:

 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;
}
 

Alors utilisez-le comme suit:

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

5voto

Ken Liu Points 7779

Vous pouvez également utiliser la classe QueryLoader dans Apache Commons DbUtils , qui lira le SQL à partir d'un fichier de propriétés. Cependant, vous devrez utiliser DbUtils qui remplit en quelque sorte le même objectif que JDBCTemplate.

1voto

Dave Points 2870

Je vous encourage fortement à utiliser les procédures stockées. Ce genre de chose est exactement ce qu'ils sont.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X