Plantilla JDBC de Primavera para llamar a Procedimientos Almacenados


¿Cuál es la forma correcta de invocar procedimientos almacenados utilizando la plantilla JDBC de primavera moderna (circa 2012)?

Digamos, tengo un procedimiento almacenado que declara ambos parámetros IN y OUT, algo así:

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

Me he encontrado con CallableStatementCreator enfoques basados en los que tenemos que registrar explícitamente IN y OUT parámetros. Considere el siguiente método en la clase JdbcTemplate:

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

Por supuesto, sé que puedo usarlo así: {[14]]}

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);

¿Qué es el propósito de declaredParameters cuando ya los estoy registrando en mi csc implementación? En otras palabras, ¿por qué tendría que pasar en un csc cuando la primavera puede simplemente hacer con.prepareCall(sql) internamente? Básicamente, ¿no puedo pasar uno de ellos en vez de los dos?

O, ¿hay una manera mucho mejor de llamar a procedimientos almacenados (usando Plantilla JDBC de Primavera) que la que he encontrado hasta ahora?

Nota: Puede encontrar muchas preguntas que parecen tener un título similar, pero no lo son el mismo que este.

Author: Vishnu, 2012-02-20

4 answers

Hay varias formas de llamar a los procedimientos almacenados en primavera.

Si usa CallableStatementCreator para declarar parámetros, estará utilizando la interfaz estándar de Java de CallableStatement, es decir, registrará los parámetros y los establecerá por separado. Usando SqlParameter abstracción hará su código más limpio.

Te recomiendo que mires SimpleJdbcCall. Se puede usar así:

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

Para procedimientos simples puede usar el método jdbcTemplate's update:

jdbcTemplate.update("call SOME_PROC (?, ?)", param1, param2);
 74
Author: Infeligo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-20 13:20:50

Estas son las formas de llamar a los procedimientos almacenados desde 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();

Aquí administramos externamente el cierre de recursos

2. Usando 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. Use 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. Utilice la clase StoredProcedure de org.springframework.jdbc.objeto

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");

Referencia

 21
Author: Sairam Kukadala,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-28 21:50:11

Generalmente prefiero extender la clase basada en Spring StoredProcedure para ejecutar procedimientos almacenados.

  1. Necesita crear su constructor de clase y necesita llamar a StoredProcedure constructor de clase en él. Este constructor de superclase acepta el origen de datos y el nombre del procedimiento.

    Código de ejemplo:

    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 ejecutar método de llamada de procedimiento almacenado como se muestra a continuación

    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;
             }
    

Espero que esto te ayude.

 17
Author: VivekDandale,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-09 11:20:09

Una forma más de llamar al procedimiento almacenado es:

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

En este ejemplo 'ClientInvestigateDTO' es la clase POJO y 'ClientInvestigateMapper' es la clase mapper.'client' almacena todo el resultado que obtiene al llamar al procedimiento almacenado.

 1
Author: Aditee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-02 10:21:36