В моей библиотеке сопряжения базы данных jOOQ, я хотел бы добавить поддержку пакетов Oracle (или DB2 и т. Д.). Я уже реализовал поддержку хранимых процедур/функций, где каждый сохраненный объект моделируется как сгенерированный Java-класс. Например, эта хранимая функцияСопоставление между пакетами Oracle и пакетами Java
CREATE FUNCTION f_author_exists (author_name VARCHAR2) RETURNS NUMBER;
будет создать класс, который может быть использован как (обратите внимание, есть также множество удобных методов, этот пример как раз показывает общий дизайн):
// A new "function call instance". The function needs to be instanciated
// once per call
FAuthorExists f = new FAuthorExists();
// Set the function parameters on the call instance and call it
f.setAuthorName("Paulo");
f.execute(connection);
// Fetch the result from the function call instance
BigDecimal result = f.getReturnValue();
Причина, по которой я выбрал сопоставление SQL-функция ->Java-класс объясняется тем, что хранимые процедуры позволяют получить комплексные возвращаемые значения (несколько параметров OUT или IN OUT), которые я хочу получить один за другим после вызова процедуры:
p.getOutParam1();
p.getOutParam2();
Теперь эта конструкция отлично работает с сохраненными функций/процедур, где перегрузки не представляется возможным. В пакеты Oracle (или в DB2), однако, я могу иметь несколько функций с тем же именем, как и
CREATE PACKAGE my_package IS
FUNCTION f_author_exists (name VARCHAR2) RETURNS NUMBER;
FUNCTION f_author_exists (name VARCHAR2, country VARCHAR2) RETURNS NUMBER;
END my_package;
Когда я создать класс за функции (или процедуры), у меня будет именования столкновения с несколькими FAuthorExists
классов Java , Хлопочным решением является добавление индекса к имени класса, например FAuthorExists2
, FAuthorExists3
. Другим хромым решением является генерация какого-либо хэш-значения (или самого значения) из имен/типов параметров непосредственно в имя класса, например FAuthorExistsVARCHAR2
, FAuthorExistsVARCHAR2VARCHAR2
. По очевидным причинам ни одно из решений не желательно.
У кого-нибудь есть простое решение этой проблемы? Или, может быть, идея лучшего общего дизайна, которая не вызывала бы такие проблемы с перегрузкой имени функции?
Любая оценка приветствуется!
Метод 'execute()' выполняет фактический вызов. Метод называется 'setName()' из-за аргумента функции 'name'. Я исправил это в примере, чтобы сделать его более понятным. Ваша идея не плохая. Хотя проблема состоит в том, что если вы перегружаете имя функции с помощью очень разных наборов аргументов, тогда может возникнуть путаница выяснить, какая комбинация аргументов возможна. Но с помощью удобных методов это может сработать! +1 для идеи определения правильного вызова во время выполнения –
Соответствие @Lukas по типам аргументов, а не имен, было тем, что я имел в виду под моим предложением - я думал, что это может быть проще. Я думаю, что в принципе возможно. – 2010-12-14 15:48:32
Легко найти хорошую реализацию о том, как вызвать функцию, основанную на именах/типах аргументов. Но сложная задача - сделать сгенерированный код простым в использовании для разработчиков. Вот почему я использую имя аргумента в сгенерированных методах –