Сопоставление пакетов Oracle и пакетов Java

в моей библиотеке интерфейсов базы данных jOOQ, Я хотел бы добавить поддержку пакетов Oracle (или DB2 и т. д.). Я уже реализовал поддержку хранимых процедур / функций, где каждый хранимый объект моделируется как сгенерированный класс 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. Другим хромым решением является создание некоторого хэш-значения (или самого значения) из имен параметров/типов непосредственно в classname, например FAuthorExistsVARCHAR2, FAuthorExistsVARCHAR2VARCHAR2. Ни одно из решений не является желательным по очевидным причинам.

у кого-нибудь есть простой решение этой проблемы? Или, может быть, идея лучшего общего дизайна, который не будет создавать такие проблемы перегрузки имени функции?

любая обратная связь ценится!

3 ответов


код getReturnValue функция может определить во время вызова, какая перегруженная функция для вызова в зависимости от того, сколько входных параметров было установлено - но я думаю, что это будет проще, если вы придерживаетесь чего-то вроде setParam1, а не setName


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

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;

произведет эти классы:

public class FAuthorExists1 { /* ... */ }
public class FAuthorExists2 { /* ... */ }

другие идеи просто вызовут новые конфликты во время генерации кода или во время выполнения.

обновление: обратите внимание, что это решение также кажется единственным, чтобы правильно обрабатывать такие ситуации:

CREATE PACKAGE my_package IS
  PROCEDURE f_author_exists (name VARCHAR2);
  PROCEDURE f_author_exists (name CHAR);
  PROCEDURE f_author_exists (name CHAR, country OUT VARCHAR2);
END my_package;

как кажется, это своего рода перегрузка возможно и в PL / SQL тоже.


вы можете преодолеть ограничения перегрузки, давая уникальные имена для каждой функции. Это также улучшило бы читаемость кода (это одна из причин почему Golang не имеет перегрузки). Например, f_author_name_exists, f_author_name_country_exists.

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