Pregunta Java - Evitar largas consultas SQL en el código


En mi código Java, tengo algo como esto:

ResultSet rs = statement.executeQuery(
                   "SELECT a,b,c FROM foo -- here starts the long query"+
                   " -- that is not yet finished " +
                   " -- that still has something to say... "+ 
                   " -- now the end !"
               );

Me gustaría limpiar mi código así:

ResultSet rs = statement.executeQuery(all_queries.getQuery("The very long one"));

He leído eso ResourceBundle es para localización Así que no creo que coincida en mi caso.

Que debería all_queries ser?

EDITAR: Lo más importante para mí es limpiar el código.


9
2017-07-25 11:06


origen


Respuestas:


Lo pondría en un archivo con una extensión SQL e implementaría Queries me gusta:

Queries {
    static public String getQuery(String name) {
        return loadResource("/com/example/queries/" + name + ".sql");
    }
}

Usuario:

conn.prepareStatement(Queries.getQuery("my_query"));

Por supuesto, esa es solo una forma de hacerlo. Puedes hacer Queries regreso Statement, o incluso utilizar un proxy dinámico para enmascararlo detrás de una interfaz Java simple (donde el controlador proxy podría crear una declaración, establecer parámetros y ejecutar una consulta). Su experiencia puede ser diferente.

Beneficio adicional: los archivos sql tienen coloración de sintaxis y son camino más fácil de mantener que Strings en Java.


11
2017-07-25 11:34



Perspectiva de la estructura de datos

Dado que necesita una asignación de una clave (nombre) a valor (consulta larga), que se logra utilizando una diccionario (también conocido como mapa, matriz asociativa) estructura de datos.

Mantenga su configuración lejos de su código

Debe almacenar su configuración en un archivo, separado de su código. Recomiendo el .ini El formato de configuración, que es muy legible, se puede dividir en secciones y tiene un buen analizador para casi cualquier lenguaje de computadora.

Su archivo de configuración se verá así:

[users_queries]    
find_max_user_id = SELECT max(id) 
                   FROM users 
                   WHERE ...
name             = query
...
...

Utilizando el ini4j módulo, obtener sus consultas sería tan fácil como:

Ini.Section section = ini.get("users_queries");
String query = section.get("find_max_user_id");

3
2017-07-25 11:08



Yo solo los haría

 static final String someMeaningfulName = " ... ";

La externalización a un archivo de texto como un paquete de recursos funcionaría, pero no estoy convencido de que sea necesario, o incluso una buena idea, ya que podría llevar a una forma de pensar que estos no son realmente "código" y por lo tanto, los cambios no Realmente no necesito pruebas.


2
2017-07-25 11:12



Una solución simple sería usar el archivo de propiedades normal, la respuesta es de La forma más limpia de construir una cadena de SQL en Java

El único problema es que la nueva línea debe separarse por "\" p.ej.

CURRENT_DATE=select sysdate \
from dual

entonces puedes usar

Queries.getQuery("CURRENT_DATE");

Sí, "\" sigue siendo feo, pero es más limpio y fácil de formatear en comparación con el uso de la concatenación String / StringBuilder de Java, imo.


Si desea admitir un formato más limpio, tal vez pueda crear su propio analizador o utilizar el formato XML. Pero creo que es un exceso.


Fuera de tema: tengo que amar Groovy's multiline String (sinvergüenza):

public static final String MY_QUERY = """\
  select col1, col2
  from table1
  where col1=:param1
""";

1
2017-07-25 11:28



Un HashMap sería simple, ya que desea mapear desde un nombre / clave de consulta a una consulta / valor. Cualquier mapa sería realmente.

public class Queries extends HashMap {
    public Queries() {
        add("My long query",
            "Super long..."+
            "...long long..."+
            "...long query.");
        // add others
    }
}

Puede usar un singleton si quiere mantenerlo estático.

public class Queries {
    private static HashMap store = new HashMap();
    {
        // constructor
        add("My long query",
            "Super long..."+
            "...long long..."+
            "...long query.");
        // add others
    }
    public String getQuery(String queryName) { return store.get(queryName); }

O simplemente podría usar cadenas estáticas como lo sugiere djna:

public class Queries {
    final public static myQuery = "My long query";
}

public class MyProgram extends Queries {
    ...
    public void someMethod() {
        ...
        doQuery(myQuery);
        ...
    }
}

0
2017-07-25 11:12



Tal vez el problema esté en la estructura de tu aplicación. ¿Separe sus clases de Java en paquetes "dao", "servicio", etc.?

Si organiza su proyecto, no necesitará llamar ResultSet rs = statement.executeQuery( all_queries.getQuery("The very long one") ), pero en vez de llamar Result res = dao.getSomethingYouNeed(param1, param2, ...);


0
2017-07-25 11:26



Si escribimos varias consultas en un archivo de texto (no en un archivo de propiedades), podemos recuperar o recuperar una sola consulta de todas.


0
2018-01-22 17:02



¡MyBatis lo hace de la caja y funciona como campeón!


-1
2018-02-07 23:22