Java-избегание длинного SQL-запроса в коде

в моем коде Java у меня есть что-то вроде этого :

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

Я хотел бы очистить свой код следующим образом:

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

Я читал, что ResourceBundle для локализации. Так что я не думаю, что это соответствует моему случаю.

что нужно all_queries быть ?

EDIT: Самое главное для меня-это очистить код.

8 ответов


Я бы поместил его в файл с расширением sql и реализовал Queries как:

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

пользователь:

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

конечно, это только один способ сделать это. Вы можете сделать Queries возвращение Statement или даже использовать динамический прокси, чтобы замаскировать его за простым интерфейсом Java (где обработчик прокси может создавать оператор, устанавливать параметры и запускать запрос). Ваш пробег может отличаться.

добавлено преимущество: файлы sql имеют синтаксическую раскраску и являются путь легче поддерживайте, чем строки в Java.


точки зрения структура данных

поскольку вам нужно сопоставление ключа (имени) со значением (длинный запрос), которое достигается с помощью словарь (он же карта, ассоциативный массив) datastructure.

держите конфигурацию подальше от кода

вы должны хранить свою конфигурацию в файле, отдельно от вашего кода. Я рекомендую .ini формат конфигурации, который очень читаем, можно разделить на разделы и имеет хороший парсер практически для любого компьютерного языка.

ваш файл конфигурации будет выглядеть так:

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

С помощью ini4j модуль, получение ваших запросов будет так же просто, как:

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

Я бы просто сделал их

 static final String someMeaningfulName = " ... ";

экстернализация в текстовый файл, такой как пакет ресурсов, будет работать, но я не уверен, что это необходимо, или даже хорошая идея, поскольку это может привести к тому, что это не совсем "код", и, следовательно, изменения действительно не нуждаются в тестировании.


простым решением было бы использовать обычный файл свойств, ответ от самый чистый способ построить строку SQL в Java

единственная проблема заключается в том, что новая строка должна быть разделена "\" например,

CURRENT_DATE=select sysdate \
from dual

затем вы можете использовать

Queries.getQuery("CURRENT_DATE");

Да, " \ " по-прежнему уродливо, но это чище и проще форматировать по сравнению с использованием Java String / StringBuilder concatenation, imo.


Если вы хотите поддерживать более чистый формат, может быть, вы можете создать свой собственный парсер или использовать формат XML. Но я думаю, что это перебор.


Off тема: Gotta love в Groovyмногострочная строка (бесстыдная):

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

HashMap будет простым, так как вы хотите сопоставить имя/ключ запроса с запросом/значением. Любая карта сойдет.

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

вы можете использовать синглтон, если хотите сохранить его статическим.

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

или вы можете просто использовать статические строки, как предложено djna:

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

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

возможно, проблема заключается в структуре вашего приложения. Вы разделяете свои классы java на пакеты" dao"," service " и т. д.?

Если вы организуете свой проект, вам не нужно будет звонить ResultSet rs = statement.executeQuery( all_queries.getQuery("The very long one") ), но вместо того, чтобы вызвать Result res = dao.getSomethingYouNeed(param1, param2, ...);


Если мы пишем несколько запросов в текстовом файле (не в файле свойств), мы можем получить или получить один запрос из всех.


MyBatis это из коробки и работает как чемпион!