2009-05-14 33 views
7

Estoy utilizando el marco de persistencia de Spring para mi proyecto. Deseo llamar a la función oracle o al procedimiento almacenado desde este marco.¿Cómo llamar a la función de Oracle o al procedimiento almacenado utilizando el marco de persistencia de resorte?

¿Alguien puede sugerir cómo puedo lograr esto.

Proporcione una solución para la función * oracle y * procedimiento almacenado.

Gracias.

+0

primavera tiene un framework de persistencia? ¿Te refieres a Spring's JdbcTemplate? ¿O Hibernate? –

+0

He usado DPTK para crear el marco de persistencia y la fábrica de consultas de Spring. Ahora quiero llamar a la función oracle o procedimiento almacenado utilizando la funcionalidad existente, ¿me pueden ayudar a ordenar esto ... –

+0

DPTK parece ser un producto de IBM: http://www.alphaworks.ibm.com/tech/dptk –

Respuesta

32

Suponiendo que estamos refiriendo a JdbcTemplate:

jdbcTemplate.execute(
    new CallableStatementCreator() { 
     public CallableStatement createCallableStatement(Connection con) throws SQLException{ 
      CallableStatement cs = con.prepareCall("{call MY_STORED_PROCEDURE(?, ?, ?)}"); 
      cs.setInt(1, ...); // first argument 
      cs.setInt(2, ...); // second argument 
      cs.setInt(3, ...); // third argument 
      return cs; 
     } 
    }, 
    new CallableStatementCallback() { 
     public Object doInCallableStatement(CallableStatement cs) throws SQLException{ 
      cs.execute(); 
      return null; // Whatever is returned here is returned from the jdbcTemplate.execute method 
     } 
    } 
); 

Llamar a una función es casi idéntico:

jdbcTemplate.execute(
    new CallableStatementCreator() { 
     public CallableStatement createCallableStatement(Connection con) { 
      CallableStatement cs = con.prepareCall("{? = call MY_FUNCTION(?, ?, ?)}"); 
      cs.registerOutParameter(1, Types.INTEGER); // or whatever type your function returns. 
      // Set your arguments 
      cs.setInt(2, ...); // first argument 
      cs.setInt(3, ...); // second argument 
      cs.setInt(4, ...); // third argument 
      return cs; 
     } 
    }, 
    new CallableStatementCallback { 
     public Object doInCallableStatement(CallableStatement cs) { 
      cs.execute(); 
      int result = cs.getInt(1); 
      return result; // Whatever is returned here is returned from the jdbcTemplate.execute method 
     } 
    } 
); 
+0

aquí estamos llamando a SP, ¿cómo podemos llamar a Oracle Function ... No me estoy refiriendo a JdbcTemplate, estoy reffering persistence framework usando DPTK .. –

+0

El segundo ejemplo es llamar a una función. Desafortunadamente, no estoy familiarizado con DPTK. ¿Tiene un sitio web? –

+0

de acuerdo, intentaré implementar esto con mi código ... espero que funcione ... Gracias Adam, te dejaré saber el resultado. –

17

manera más simple de llamar a una función de Oracle en primavera es la subclasificación StoredProcedure, como a continuación

public class MyStoredProcedure extends StoredProcedure{ 
    private static final String SQL = "package.function"; 

    public MyStoredProcedure(DataSource ds){ 
     super(ds,SQL); 
     declareParameter(new SqlOutParameter("param_out",Types.NUMERIC)); 
     declareParameter(new SqlParameter("param_in",Types.NUMERIC)); 
     setFunction(true);//you must set this as it distinguishes it from a sproc 
     compile(); 
    } 

    public String execute(Long rdsId){ 
     Map in = new HashMap(); 
     in.put("param_in",rdsId); 
     Map out = execute(in); 
     if(!out.isEmpty()) 
      return out.get("param_out").toString(); 
     else 
      return null; 
    } 
} 

Y llámalo así

@Autowired DataSource ds; 
MyStoredProcedure sp = new MyStoredProcedure(ds); 
String i = sp.execute(1l); 

La función de Oracle utilizada aquí solo toma un parámetro numérico y devuelve un parámetro numérico.

+0

como entiendo que el código SQL debería verse así: '{: param_out = invocar schema.package.MY_FUNCTION (: param_in)}' – mmoossen

+0

mi último comentario es incorrecto. la constante SQL debe contener solo el nombre del procedimiento/función, como 'schema.package.MY_FUNCTION', y los nombres de los parámetros en Java ** HAVE ** para que coincidan con los nombres de los parámetros definidos en el procedimiento/función. – mmoossen

0

En mi opinión, este es uno de los enfoques más sencillos:

public class ServRepository { 

    private JdbcTemplate jdbcTemplate; 
    private SimpleJdbcCall functionGetServerErrors; 

    @Autowired 
    public void setDataSource(DataSource dataSource) { 
     this.jdbcTemplate = new JdbcTemplate(dataSource); 
     JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); 
     jdbcTemplate.setResultsMapCaseInsensitive(true); 
     this.functionGetServerErrors = new SimpleJdbcCall(jdbcTemplate).withFunctionName("THIS_IS_YOUR_DB_FUNCTION_NAME").withSchemaName("OPTIONAL_SCHEMA_NAME"); 
    } 

     public String callYourFunction(int parameterOne, int parameterTwo) { 
      SqlParameterSource in = new MapSqlParameterSource().addValue("DB_FUNCTION_INCOMING_PARAMETER_ONE", parameterOne).addValue("DB_FUNCTION_INCOMING_PARAMETER_TWO", parameterTwo); 
      return functionGetServerErrors.executeFunction(String.class, in); 
     } 
} 
Cuestiones relacionadas