Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - Storing SQL statements in an external file [closed]

Tags:

java

sql

jdbc

I am looking for a Java library/framework/technique of storing SQL statements in an external file. The support team (including DBAs) should be able to alter (slightly) the statement to keep them in sync in case database schema changes or for tuning purposes.

Here are the requirements:

  • The file must be readable from a Java application but also must be editable by the support team without the need of fancy editors
  • Ideally, the file should be in plain text format but XML is OK too
  • Allow DML as well as DDL statements to be stored / retrieved
  • New statements can be added at a later stage (the application is flexible enough to pick them up and execute them)
  • Statements can be grouped (and executed as a group by the application)
  • Statements should allow parameters

Notes:

  • Once retrieved, the statements will executed using Spring’s JDBCTemplate
  • Hibernate or Spring’s IOC container will not be used

So far, I managed to find the following Java libraries, which use external files for storing SQL statements. However, I am mainly interested in the storage rather than a library that hides all JDBC “complexities”.

  • Axamol SQL Library

    Sample file content:

    <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

    Sample file content:

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

Can anyone recommend a solution that is tried and tested?

like image 613
Adrian Avatar asked Oct 09 '09 14:10

Adrian


People also ask

Can I store SQL query in table?

There is no correct data type to store a query. But you can always strip HTML chars by using HTMLencode chars. Show activity on this post. If you don't need to pass in parameters you could execute a CREATE VIEW .

How do I run a .SQL file in Java?

You can execute . sql script files in Java using the runScript() method of the ScriptRunner class of Apache iBatis. To this method you need to pass a connection object. Register the MySQL JDBC Driver using the registerDriver() method of the DriverManager class.


2 Answers

Just create a simple Java Properties file with key-value pairs like this one:

users.select.all = select * from user 

Declare a private field of type Properties in your DAO class and inject it using Spring configuration which will read the values from the file.

UPDATE: if you want to support SQL statements in multiple lines use this notation:

users.select.all.0 = select * users.select.all.1 = from   user 
like image 111
Boris Pavlović Avatar answered Sep 19 '22 13:09

Boris Pavlović


Pasting here my answer to Clean way to externalize long (+20 lines sql) when using spring jdbc?:

I faced the same issue some time ago, and came up with YAML. It supports multi-line string property values, so you can write something like this in your query files:

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

Here, selectSomething and insertSomething are query names. So it's really convenient and contains very few special characters. Queries are separated by blank lines, and each query text must be indented. Note that queries can absolutely contain the indentation of their own, so that the following is perfectly valid:

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

You can then read the contents of the file into a hash-map with the help of SnakeYAML library, using the code below:

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!!!");     }   } } 

In the example above a map of maps is created, mapping each YAML file to a map containing query names/strings.

like image 44
siphiuel Avatar answered Sep 19 '22 13:09

siphiuel