web-dev-qa-db-ja.com

ストアドプロシージャを呼び出すためのSpring JDBCテンプレート

現代(2012年頃)のSpring JDBCテンプレートを使用してストアドプロシージャを呼び出す正しい方法は何ですか?

たとえば、次のような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の目的は何ですか?言い換えれば、スプリングが内部で単にcon.prepareCall(sql)できるのに、なぜcscを渡す必要があるのでしょうか?基本的に、両方ではなくどちらか一方を渡すことはできませんか?

または、これまでに出会った方法よりもはるかに優れたストアドプロシージャ(Spring JDBCテンプレートを使用)を呼び出す方法がありますか?

注:タイトルが似ているように見える質問がたくさんありますが、この質問とは異なります。

69
adarshr

Springでストアドプロシージャを呼び出す方法はいくつかあります。

CallableStatementCreatorを使用してパラメーターを宣言する場合は、JavaのCallableStatementの標準インターフェースを使用します。つまり、パラメーターを登録して個別に設定します。 SqlParameter抽象化を使用すると、コードがきれいになります。

SimpleJdbcCallをご覧になることをお勧めします。次のように使用できます。

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

簡単な手順では、jdbcTemplateupdateメソッドを使用できます。

jdbcTemplate.update("call SOME_PROC (?, ?)", param1, param2);
85
Infeligo

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。 org.springframework.jdbc.objectのStoredProcedureクラスを使用します

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

参照

27
Sairam Kukadala

通常、SpringベースのStoredProcedureクラスを拡張してストアドプロシージャを実行することを好みます。

  1. クラスコンストラクターを作成し、その中でStoredProcedureクラスコンストラクターを呼び出す必要があります。このスーパークラスコンストラクターは、DataSourceとプロシージャ名を受け入れます。

    サンプルコード:

    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. 以下のように、ストアドプロシージャコールの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;
             }
    

これがお役に立てば幸いです。

17
VivekDandale

ストアドプロシージャを呼び出すもう1つの方法は次のとおりです。

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

この例では、「ClientInvestigateDTO」はPOJOクラスであり、「ClientInvestigateMapper」はマッパークラスです。「client」は、ストアドプロシージャの呼び出しで取得したすべての結果を格納します。

1
Aditee