Java - Избегание длинных SQL-запросов в коде - PullRequest
9 голосов
/ 25 июля 2011

В моем коде 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?

РЕДАКТИРОВАТЬ: Самое главное для меня - очистить код.

Ответы [ 8 ]

11 голосов
/ 25 июля 2011

Я бы поместил его в файл с расширением 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.

3 голосов
/ 25 июля 2011

Перспектива структуры данных

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

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

Вы должны хранить свою конфигурацию в файле, отдельном от вашего кода. Я рекомендую формат конфигурации

.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");
2 голосов
/ 25 июля 2011

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

 static final String someMeaningfulName = " ... ";

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

1 голос
/ 25 июля 2011

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

Единственная проблема заключается в том, что новую строку необходимо отделить«\» Например,

CURRENT_DATE=select sysdate \
from dual

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

Queries.getQuery("CURRENT_DATE");

Да, «\» все еще безобразно, но его чище и легче форматировать по сравнению с использованием конкатенации Java String / StringBuilder,ИМО.

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


Оффтопик: Gotta love Groovy многострочная строка (бесстыдная):

public static final String MY_QUERY = """\
  select col1, col2
  from table1
  where col1=:param1
""";
0 голосов
/ 08 февраля 2014

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

0 голосов
/ 22 января 2013

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

0 голосов
/ 25 июля 2011

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

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

0 голосов
/ 25 июля 2011

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);
        ...
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...