Nella libreria di interfacciamento del database jOOQ, desidero aggiungere il supporto per i pacchetti Oracle (o DB2, ecc.). Ho già implementato il supporto di stored procedure/funzioni in cui ogni oggetto memorizzato è modellato come una classe Java generata. Ad esempio, questa funzione memorizzataMappatura tra pacchetti Oracle e pacchetti Java
CREATE FUNCTION f_author_exists (author_name VARCHAR2) RETURNS NUMBER;
genererà una classe che può essere utilizzato in questo modo (si noti, ci sono anche un sacco di metodi di convenienza, questo esempio dimostra il disegno generale):
// 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 ragione per cui ho scelto una funzione ->- Java classe è perché le stored procedure consentono valori di ritorno complessi (diversi parametri OUT o IN OUT) che desidero essere in grado di recuperare uno dopo l'altro chiamando la procedura:
p.getOutParam1();
p.getOutParam2();
Ora questo disegno funziona correttamente con le funzioni/procedure memorizzate, dove sovraccarico non è possibile. All'interno dei pacchetti di Oracle (o DB2), tuttavia, posso avere diverse funzioni con lo stesso nome, come
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;
Quando ho generare una classe per ogni funzione (o procedure), avrò gli scontri di denominazione con diversi FAuthorExists
classi Java . Una soluzione zoppa consiste nell'aggiungere un indice al nome della classe, ad esempio FAuthorExists2
, FAuthorExists3
. Un'altra soluzione zoppa è generare una sorta di valore hash (o il valore stesso) dai nomi/tipi dei parametri direttamente nel nome classe, come FAuthorExistsVARCHAR2
, FAuthorExistsVARCHAR2VARCHAR2
. Nessuna soluzione è auspicabile per ovvi motivi.
Qualcuno ha una soluzione semplice a questo problema? O forse un'idea di un design complessivo migliore che non produrrebbe problemi di sovraccarico di questo nome di funzione?
Qualsiasi feedback apprezzato!
Il metodo 'execute()' effettua la chiamata effettiva. Il metodo è chiamato 'setName()' a causa dell'argomento function 'name'. L'ho risolto nell'esempio, per renderlo più chiaro. La tua idea non è cattiva. Sebbene, il problema è che se si ha un sovraccarico del nome della funzione con insiemi di argomenti molto distinti, allora potrebbe diventare difficile scoprire quale combinazione di argomenti sia possibile. Ma con i metodi di convenienza, potrebbe funzionare! +1 per l'idea di determinare la chiamata corretta al momento dell'esecuzione –
@Lukas corrispondente ai tipi di argomenti piuttosto che ai nomi era ciò che intendevo per il mio suggerimento - pensavo che potesse essere più semplice. Penso che entrambi sarebbero possibili in linea di principio però. –
È facile trovare una buona implementazione su come chiamare la funzione in base ai nomi degli argomenti/tipi/posizione. Ma la parte difficile è rendere il codice generato facile da usare per gli sviluppatori. Ecco perché uso il nome dell'argomento nei metodi generati –