2012-02-20 10 views
54

Qual è il modo corretto di richiamare le stored procedure utilizzando il modello JDBC Spring moderno (circa 2012)?Modello JDBC primaverile per la chiamata di stored procedure

Di ', ho una stored procedure che dichiara sia IN e OUT parametri, qualcosa di simile:

mypkg.doSomething(
    id OUT int, 
    name IN String, 
    date IN Date 
) 

mi sono imbattuto CallableStatementCreator approcci basati in cui dobbiamo registrare in modo esplicito IN e OUT parametri. Si consideri il seguente metodo in JdbcTemplate classe:

public Map<String, Object> call(CallableStatementCreator csc, List<SqlParameter> declaredParameters) 

Naturalmente, so che posso utilizzarlo in questo modo:

List<SqlParameter> declaredParameters = new ArrayList<SqlParameter>(); 

declaredParameters.add(new SqlOutParameter("id", Types.INTEGER)); 
declaredParameters.add(new SqlParameter("name", Types.VARCHAR)); 
declaredParameters.add(new SqlParameter("date", Types.DATE)); 

this.jdbcTemplate.call(new CallableStatementCreator() { 

    @Override 
    CallableStatement createCallableStatement(Connection con) throws SQLException { 
     CallableStatement stmnt = con.createCall("{mypkg.doSomething(?, ?, ?)}"); 

     stmnt.registerOutParameter("id", Types.INTEGER); 
     stmnt.setString("name", "<name>"); 
     stmnt.setDate("date", <date>); 

     return stmnt; 
    } 
}, declaredParameters); 

Qual è lo scopo della declaredParameters quando sto già li si registrano nel mio Implementazione csc? In altre parole, perché dovrei passare in un csc quando la primavera può semplicemente fare con.prepareCall(sql) internamente? Fondamentalmente, non posso passare in uno di essi invece di entrambi?

Oppure, c'è un modo molto migliore per chiamare stored procedure (utilizzando Spring JDBC Template) rispetto a quello che ho trovato finora?

Nota: È possibile trovare molte domande che sembrano avere un titolo simile ma non sono le stesse di questo.

+2

Posso vedere che questa domanda è abbastanza popolare ora e sono già passati più di 2 anni da quando è stato chiesto. Se qualcuno pensa che ci sia un modo ancora più bello di chiamare stored procedure ora che Spring 4 è fuori, si prega di inviare una risposta o suggerire una modifica. – adarshr

risposta

67

Ci sono diversi modi per chiamare le stored procedure in primavera.

Se si utilizza CallableStatementCreator per dichiarare i parametri, si utilizzerà l'interfaccia standard Java di CallableStatement, quindi i parametri di registrazione vengono impostati e impostati separatamente. L'uso dell'astrazione SqlParameter renderà il tuo codice più pulito.

Ti consiglio di guardare SimpleJdbcCall. Esso può essere utilizzato in questo modo:

SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate) 
    .withSchemaName(schema) 
    .withCatalogName(package) 
    .withProcedureName(procedure)(); 
... 
jdbcCall.addDeclaredParameter(new SqlParameter(paramName, OracleTypes.NUMBER)); 
... 
jdbcCall.execute(callParams); 

Per le procedure semplici che si possono utilizzare jdbcTemplate s' update metodo:

jdbcTemplate.update("call SOME_PROC (?, ?)", param1, param2); 
+0

'SimpleJdbcCall' sembra davvero bello. Lo metterò alla prova e ti farò sapere come è andata nel mio caso. – adarshr

+3

È stato un piacere lavorare con 'SimpleJdbcCall'. Grazie. – adarshr

+2

Il metodo di aggiornamento non ha funzionato per me, ho ricevuto un'eccezione di grammatica SQL negativa anche se la mia istruzione è stata eseguita correttamente nel database. SimpleJdbcCall ha funzionato molto bene – memo

17

io in genere preferisco estendere Spring sulla base StoredProcedure classe per eseguire le stored procedure.

  1. È necessario creare il costruttore di classe e la necessità di chiamare StoredProcedure costruttore della classe in esso. Questo costruttore di super classi accetta DataSource e il nome della procedura.

    codice Esempio:

    public class ProcedureExecutor extends StoredProcedure { 
         public ProcedureExecutor(DataSource ds, String funcNameorSPName) { 
         super(ds, funcNameorSPName); 
         declareParameter(new SqlOutParameter("v_Return", Types.VARCHAR, null, new SqlReturnType() { 
           public Object getTypeValue(CallableStatement cs, 
            int paramIndex, int sqlType, String typeName) throws SQLException { 
           final String str = cs.getString(paramIndex); 
           return str; 
          }   
         }));  
         declareParameter(new SqlParameter("your parameter", 
           Types.VARCHAR)); 
         //set below param true if you want to call database function 
         setFunction(true); 
         compile(); 
         } 
    
  2. Override metodo di chiamata di stored procedure eseguire come di seguito

    public Map<String, Object> execute(String someParams) { 
          final Map<String, Object> inParams = new HashMap<String, Object>(8); 
          inParams.put("my param", "some value"); 
          Map outMap = execute(inParams); 
          System.out.println("outMap:" + outMap); 
          return outMap; 
         } 
    

Spero che questo ti aiuta.

11

Ecco i modi per chiamare le stored procedure da Java

1. Usando CallableStatement:

connection = jdbcTemplate.getDataSource().getConnection(); 
    CallableStatement callableStatement = connection.prepareCall("{call STORED_PROCEDURE_NAME(?, ?, ?)}"); 
    callableStatement.setString(1, "FirstName"); 
    callableStatement.setString(2, " LastName"); 
    callableStatement.registerOutParameter(3, Types.VARCHAR); 
    callableStatement.executeUpdate(); 

Qui da noi gestiti esternamente la risorsa chiusura

2. Utilizzando CallableStatementCreator

List paramList = new ArrayList(); 
    paramList.add(new SqlParameter(Types.VARCHAR)); 
    paramList.add(new SqlParameter(Types.VARCHAR)); 
    paramList.add(new SqlOutParameter("msg", Types.VARCHAR)); 

    Map<String, Object> resultMap = jdbcTemplate.call(new CallableStatementCreator() { 

    @Override 
    public CallableStatement createCallableStatement(Connection connection) 
    throws SQLException { 

    CallableStatement callableStatement = connection.prepareCall("{call STORED_PROCEDURE_NAME(?, ?, ?)}"); 
    callableStatement.setString(1, "FirstName"); 
      callableStatement.setString(2, " LastName"); 
      callableStatement.registerOutParameter(3, Types.VARCHAR); 
    return callableStatement; 

    } 
    }, paramList); 

3. Utilizzare SimpleJdbcCall: classe

SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(jdbcTemplate) 

.withProcedureName("STORED_PROCEDURE_NAME"); 

Map<String, Object> inParamMap = new HashMap<String, Object>(); 
inParamMap.put("firstName", "FirstNameValue"); 
inParamMap.put("lastName", "LastNameValue"); 
SqlParameterSource in = new MapSqlParameterSource(inParamMap); 


Map<String, Object> simpleJdbcCallResult = simpleJdbcCall.execute(in); 
System.out.println(simpleJdbcCallResult); 

4. Utilizzo StoredProcedure di org.springframework.jdbc.object

The Code: 
First Create subclass of StoredProcedure: MyStoredProcedure 

class MyStoredProcedure extends StoredProcedure { 

public MyStoredProcedure(JdbcTemplate jdbcTemplate, String name) { 

super(jdbcTemplate, name); 
setFunction(false); 

} 

} 

Use MyStoredProcedure to call database stored procedure: 


//Pass jdbcTemlate and name of the stored Procedure. 
MyStoredProcedure myStoredProcedure = new MyStoredProcedure(jdbcTemplate, "PROC_TEST"); 

//Sql parameter mapping 
SqlParameter fNameParam = new SqlParameter("fName", Types.VARCHAR); 
SqlParameter lNameParam = new SqlParameter("lName", Types.VARCHAR); 
SqlOutParameter msgParam = new SqlOutParameter("msg", Types.VARCHAR); 
SqlParameter[] paramArray = {fNameParam, lNameParam, msgParam}; 


myStoredProcedure.setParameters(paramArray); 
myStoredProcedure.compile(); 


//Call stored procedure 
Map storedProcResult = myStoredProcedure.execute("FirstNameValue", " LastNameValue"); 

Reference

+0

Che aspetto avrebbe questo se avessi una procedura di restituzione a più righe? Sarebbe un elenco di oggetti Map? –

+0

@Kent: sei corretto. Sarebbe List > per più righe. –

1

Un altro modo per chiamare stored la procedura è:

sql="execute Procedure_Name ?"; 
Object search[]={Id}; 
List<ClientInvestigateDTO> client=jdbcTemplateObject.query(sql,search,new 
    ClientInvestigateMapper()); 

In questo esempio 'ClientInvestigateDTO' è la classe POJO e 'ClientInvestigateMapper' è la classe mapper.'client 'memorizza tutti i risultati ottenuti chiamando la stored procedure.

Problemi correlati