2012-02-20 77 views
54

Cách chính xác để gọi các thủ tục được lưu trữ bằng cách sử dụng mẫu JDBC Spring (circa 2012) hiện đại là gì?Mẫu JDBC Spring để gọi Thủ tục lưu sẵn

Nói, tôi có một thủ tục lưu trữ mà tuyên bố cả hai INOUT thông số, một cái gì đó như thế này:

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

Tôi đã đi qua CallableStatementCreator cách tiếp cận dựa trên nơi chúng tôi phải đăng ký rõ ràng INOUT tham số. Hãy xem xét các phương pháp sau đây trong JdbcTemplate lớp:

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

Tất nhiên, tôi biết rằng tôi có thể sử dụng nó như vậy:

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

mục đích declaredParameters là gì khi tôi đã đăng ký chúng trong tôi csc triển khai? Nói cách khác, tại sao tôi cần phải vượt qua trong một csc khi mùa xuân chỉ đơn giản có thể làm con.prepareCall(sql) nội bộ? Về cơ bản, tôi không thể vượt qua cả hai người trong số họ thay vì cả hai?

Hoặc, có cách nào tốt hơn để gọi thủ tục được lưu trữ (sử dụng Mẫu JDBC Spring) so với những gì tôi đã đi qua cho đến nay?

Lưu ý: Bạn có thể tìm thấy nhiều câu hỏi dường như có tiêu đề tương tự nhưng chúng không giống với tiêu đề này.

+2

Tôi có thể thấy rằng câu hỏi này khá phổ biến hiện tại và đã hơn 2 năm kể từ khi được hỏi. Nếu bất cứ ai nghĩ rằng có một cách thậm chí còn đẹp hơn để gọi thủ tục lưu trữ ngay bây giờ mà mùa xuân 4 là ra, xin vui lòng gửi một câu trả lời hoặc đề nghị một chỉnh sửa. – adarshr

Trả lời

67

Có một số cách để gọi thủ tục được lưu trữ trong Spring.

Nếu bạn sử dụng CallableStatementCreator để khai báo tham số, bạn sẽ sử dụng giao diện chuẩn của Java là CallableStatement, tức là đăng xuất tham số và đặt riêng chúng. Sử dụng SqlParameter trừu tượng sẽ làm cho mã của bạn sạch hơn.

Tôi khuyên bạn nên xem SimpleJdbcCall. Nó có thể được sử dụng như thế này:

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

Đối với thủ tục đơn giản, bạn có thể sử dụng jdbcTemplate 's update phương pháp:

jdbcTemplate.update("call SOME_PROC (?, ?)", param1, param2); 
+0

'SimpleJdbcCall' có vẻ rất tuyệt. Tôi sẽ kiểm tra điều này và cho bạn biết nó như thế nào trong trường hợp của tôi. – adarshr

+3

Thật vui khi được làm việc với 'SimpleJdbcCall'. Cảm ơn bạn. – adarshr

+2

Phương thức cập nhật không hoạt động đối với tôi, tôi đã nhận được ngoại lệ ngữ pháp SQL sai mặc dù câu lệnh của tôi được thực hiện tốt trong cơ sở dữ liệu. SimpleJdbcCall làm việc rất tốt – memo

17

Tôi thường thích để mở rộng mùa xuân dựa StoredProcedure lớp để thực hiện các thủ tục lưu trữ.

  1. Bạn cần phải tạo hàm tạo lớp và cần gọi hàm xây dựng lớp StoredProcedure trong đó. Nhà xây dựng siêu lớp này chấp nhận DataSource và tên thủ tục.

    Ví dụ mã:

    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. Ghi đè phương thức execute của cuộc gọi thủ tục lưu trữ như sau

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

Hy vọng điều này sẽ giúp bạn.

11

Dưới đây là những cách để gọi stored procedures từ java

1. Sử dụng 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(); 

Ở đây chúng ta bên ngoài quản lý tài nguyên đóng

2. Sử dụng 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. Sử dụng 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. Sử dụng StoredProcedure lớp 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"); 

Reference

+0

Điều này sẽ trông như thế nào nếu tôi có thủ tục trả hàng nhiều hàng? Nó có phải là một danh sách các đối tượng của Map không? –

+0

@Kent - Bạn đã đúng. Nó sẽ là List > cho nhiều hàng. –

1

Thêm một cách để gọi được lưu trữ thủ tục là:

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

Trong ví dụ này 'ClientInvestigateDTO' là lớp POJO và 'ClientInvestigateMapper' là lớp bản đồ.'client 'lưu trữ tất cả kết quả bạn nhận được khi gọi thủ tục được lưu trữ.

Các vấn đề liên quan