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, ...);
Если мы пишем несколько запросов в текстовом файле (не в файле свойств), мы можем получить или получить один запрос из всех.