Шаблон Spring JDBC для вызова хранимых процедур
как правильно вызывать хранимые процедуры с помощью шаблона Spring JDBC modern day (около 2012 года)?
скажем, у меня есть хранимая процедура, которая объявляет как IN и OUT параметры, что-то вроде этого:
mypkg.doSomething(
id OUT int,
name IN String,
date IN Date
)
я наткнулся CallableStatementCreator подходы, где мы должны четко прописать IN и OUT параметры. Рассмотрим следующий метод в JdbcTemplate класс:
public Map<String, Object> call(CallableStatementCreator csc, List<SqlParameter> declaredParameters)
конечно, я знаю, что могу используйте его так:
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);
какова цель declaredParameters когда я уже регистрирую их в своем csc реализация? Другими словами, Зачем мне нужно пройти в csc когда весна может просто сделать con.prepareCall(sql) внутренне? В принципе, я не могу передать ни один из них вместо них обоих?
или, есть ли гораздо лучший способ вызова хранимых процедур (с помощью шаблона Spring JDBC), чем то, с чем я столкнулся так далеко?
Примечание: вы можете найти много вопросов, которые, как представляется, имеют похожие названия, но они не такие, как этот.
4 ответов:
Существует несколько способов вызова хранимых процедур весной.
если вы используете
CallableStatementCreatorдля объявления параметров вы будете использовать стандартный интерфейс JavaCallableStatement, т. е. зарегистрировать параметры и установить их отдельно. ИспользуяSqlParameterабстракция сделает ваш код чище.я рекомендую вам смотреть на
SimpleJdbcCall. Он может быть использован следующим образом:SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate) .withSchemaName(schema) .withCatalogName(package) .withProcedureName(procedure)(); ... jdbcCall.addDeclaredParameter(new SqlParameter(paramName, OracleTypes.NUMBER)); ... jdbcCall.execute(callParams);для простых процедур вы можете использовать
jdbcTemplate' supdateспособ:jdbcTemplate.update("call SOME_PROC (?, ?)", param1, param2);
вот способы вызова хранимых процедур из java
1. Использование 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();здесь мы внешне управляем закрытием ресурса
2. Использование 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. Используйте 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. Используйте класс хранимая процедура из орг.springframework.интерфейс jdbc.объект
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");
Я вообще предпочитаю продлить весну на основе
StoredProcedureкласс для выполнения хранимых процедур.
вам нужно создать конструктор класса и нужно вызвать
StoredProcedureконструктор класса в нем. Этот конструктор суперкласса принимает имя источника данных и процедуры.пример кода:
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(); }переопределить метод execute для вызова хранимой процедуры, как показано ниже
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; }надеюсь, это поможет вы.
еще один способ вызова хранимой процедуры:
sql="execute Procedure_Name ?"; Object search[]={Id}; List<ClientInvestigateDTO> client=jdbcTemplateObject.query(sql,search,new ClientInvestigateMapper());в этом примере 'ClientInvestigateDTO' - это класс POJO, а' ClientInvestigateMapper ' - класс mapper."клиент" сохраняет все результаты, которые вы получаете при вызове хранимой процедуры.
Comments