Correspondencia entre paquetes de Oracle y paquetes de Java
-
09-10-2019 - |
Pregunta
En mi base de datos de interfaz , me gustaría añadir soporte para Oracle (o DB2, etc) paquetes de bibliotecas jOOQ . Ya he implementado soporte procedimiento / función almacenada en el que cada objeto almacenado se modela como una clase Java generado. Por ejemplo, esta función almacenada
CREATE FUNCTION f_author_exists (author_name VARCHAR2) RETURNS NUMBER;
generará una clase que puede ser utilizada como esta (nota, también hay una gran cantidad de métodos de conveniencia, este ejemplo demuestra el diseño general):
// 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();
La razón por la que elegí un mapeo función SQL -> Java Class es porque los procedimientos almacenados permiten valores de retorno complejas (varios fuera, o los parámetros IN OUT) que quiero poder a buscar uno por uno después de llamar al procedimiento:
p.getOutParam1();
p.getOutParam2();
Ahora bien este diseño trabaja con funciones / procedimientos almacenados, donde sobrecarga no es posible. Dentro de los paquetes de Oracle (o DB2 de), sin embargo, puedo tener varias funciones con el mismo nombre, como
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;
Cuando genero una clase por cada función (o procedimiento), que tendrá enfrentamientos con varios nombres FAuthorExists
clases Java. Una solución cojo es agregar un índice para el nombre de la clase, tales como FAuthorExists2
, FAuthorExists3
. Otra solución cojo es generar algún tipo de valor hash (o el valor en sí) a partir de los nombres de los parámetros / tipos directamente en el nombre de clase, tales como FAuthorExistsVARCHAR2
, FAuthorExistsVARCHAR2VARCHAR2
. Ni solución es deseable por razones obvias.
¿Alguien tiene una solución simple a este problema? O tal vez una idea de un diseño mejor en general que no produciría problemas de sobrecarga de tales nombres de función?
Cualquier comentario apreciada!
Solución 2
he encontrado ninguna otra forma viable para resolver este problema de utilizar un "índice de sobrecarga" en las clases generadas. Por lo tanto, el paquete
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;
producirá estas clases:
public class FAuthorExists1 { /* ... */ }
public class FAuthorExists2 { /* ... */ }
Otras ideas haría justa causa nuevos conflictos en el tiempo de generación de código, o en tiempo de ejecución.
Actualizar : Nota, esta solución parece también el único en situaciones como ésta mango correctamente:
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;
Por lo que parece, este tipo de sobrecarga es posible en PL / SQL, también.
Otros consejos
Su función getReturnValue
podría determinar en tiempo de llamada que la función sobrecargada llamar en función de establecer el número de parámetros de entrada han sido - pero creo que va a llegar a ser más fácil si usted se pega a algo así como setParam1
en lugar de setName
podría superar las limitaciones de la sobrecarga, dando nombres únicos para cada función. Esto también podría mejorar la legibilidad del código (que es una de las razones por qué Golang no tiene sobrecarga ). Por ejemplo f_author_name_exists, f_author_name_country_exists.
Otra forma, lo que complicará las clases de Java, es decidir en tiempo de ejecución lo que al procedimiento de llamada, en base al cual el constructor sobrecargado de Java se utiliza o que se hayan utilizado los emisores.