Was ist der richtige Weg, um gespeicherte Prozeduren mit der modernen (ca. 2012) Spring JDBC-Vorlage aufzurufen?
Angenommen, ich habe eine gespeicherte Prozedur, die sowohl IN
als auch OUT
Parameter deklariert.
mypkg.doSomething(
id OUT int,
name IN String,
date IN Date
)
Ich bin auf CallableStatementCreator
basierende Ansätze gestoßen, bei denen wir uns explizit registrieren IN
und OUT
Parameter festlegen müssen. Betrachten Sie die folgende Methode in der JdbcTemplate
Klasse:
public Map<String, Object> call(CallableStatementCreator csc, List<SqlParameter> declaredParameters)
Natürlich weiß ich, dass ich es so verwenden kann:
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);
Was ist der Zweck, declaredParameters
wenn ich sie bereits in meiner csc
Implementierung registriere ? Mit anderen Worten, warum sollte ich eine Zeit abgeben müssen, in der der csc
Frühling einfach con.prepareCall(sql)
intern funktionieren kann ? Kann ich nicht einen von beiden anstelle von beiden übergeben?
Oder gibt es eine viel bessere Möglichkeit, gespeicherte Prozeduren (mithilfe der Spring JDBC-Vorlage) aufzurufen als die, auf die ich bisher gestoßen bin?
Hinweis: Möglicherweise finden Sie viele Fragen, die einen ähnlichen Titel zu haben scheinen, aber nicht mit diesem identisch sind.
quelle
Antworten:
Es gibt verschiedene Möglichkeiten, gespeicherte Prozeduren im Frühjahr aufzurufen.
Wenn Sie
CallableStatementCreator
Parameter deklarieren, verwenden Sie die Standardschnittstelle von JavaCallableStatement
, dh registrieren Sie Parameter und legen Sie sie separat fest. Durch die Verwendung derSqlParameter
Abstraktion wird Ihr Code sauberer.Ich empfehle Ihnen zu schauen
SimpleJdbcCall
. Es kann folgendermaßen verwendet werden:SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate) .withSchemaName(schema) .withCatalogName(package) .withProcedureName(procedure)(); ... jdbcCall.addDeclaredParameter(new SqlParameter(paramName, OracleTypes.NUMBER)); ... jdbcCall.execute(callParams);
Für einfache Verfahren können Sie verwenden
jdbcTemplate
‚s -update
Methode:jdbcTemplate.update("call SOME_PROC (?, ?)", param1, param2);
quelle
SimpleJdbcCall
scheint wirklich cool. Ich werde dies testen und Sie wissen lassen, wie es in meinem Fall gelaufen ist."cannot invoke update on null object"
.jdbcTemplate.update("{ call my_schema.my_pkg.SOME_PROC (?, ?) }", param1, param2);
(Beachten Sie die geschweiften Klammern).Hier sind die Möglichkeiten, die gespeicherten Prozeduren von Java aus aufzurufen
1. Verwenden von 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();
Hier verwalten wir extern das Schließen der Ressource
2. Verwenden von 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. Verwenden Sie SimpleJdbcCall:
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. Verwenden Sie die StoredProcedure-Klasse von 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");
Referenz
quelle
Im Allgemeinen bevorzuge ich die Erweiterung der Spring-basierten
StoredProcedure
Klasse, um gespeicherte Prozeduren auszuführen.Sie müssen Ihren Klassenkonstruktor erstellen und darin den Klassenkonstruktor aufrufen
StoredProcedure
. Dieser Superklassenkonstruktor akzeptiert den Namen der DataSource und der Prozedur.Beispielcode:
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(); }
Überschreiben Sie die Ausführungsmethode des Aufrufs einer gespeicherten Prozedur wie folgt
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; }
Hoffe das hilft dir.
quelle
Eine weitere Möglichkeit, eine gespeicherte Prozedur aufzurufen, ist:
sql="execute Procedure_Name ?"; Object search[]={Id}; List<ClientInvestigateDTO> client=jdbcTemplateObject.query(sql,search,new ClientInvestigateMapper());
In diesem Beispiel ist 'ClientInvestigateDTO' die POJO-Klasse und 'ClientInvestigateMapper' die Mapper-Klasse. 'Client' speichert alle Ergebnisse, die Sie beim Aufrufen der gespeicherten Prozedur erhalten.
quelle