2012-10-04 138 views
7

我一直在使用谷歌搜索一段時間,似乎無法找到任何真正的答案。如何使用MyBatis將Java對象列表傳遞給Oracle存儲過程?

我有一個Oracle存儲過程,它有一些參數的類型是表rowtype的表。因此,例如:

在pacakge宣稱:

TYPE param1_type_t IS TABLE OF table1%ROWTYPE; 
TYPE param2_type_t IS TABLE OF table2%ROWTYPE; 
TYPE param3_type_t IS TABLE OF table3%ROWTYPE; 

Oracle過程:

PROCEDURE my_proc 
(
    parameter1 IN param1_type_t, 
    parameter2 IN param2_type_t, 
    parameter3 IN param3_type_t 
) 

在Java端,我有表示每個對象的3個相應解釋在Java中填充的參數。在這種情況下是否可以使用MyBatis調用Oracle過程?

<update id="callOracleSP" statementType="CALLABLE"> 
    {CALL my_proc(#{param1, mode=IN}, 
        #{param2, mode=IN}, 
        #{param3, mode=IN} 
       ) 
    } 
</update> 

對象本身是簡單的虛擬組織與字符串和整數屬性及其各自getter和setter。

我不太確定如何繼續。我是否需要以某種方式將Java對象列表映射到Oracle類型?

在此先感謝。

回答

7

我不知道你是否已經做了,但你需要定義Oracle對象。

CREATE OR REPLACE TYPE SCHEMA."YOUR_OBJECT" AS OBJECT 
(
    field_one varchar2(50), 
    field_two varchar2(100) 
); 
/
CREATE OR REPLACE TYPE SCHEMA."YOUR_OBJECT_ARRAY" AS TABLE OF YOUR_OBJECT; 
/

然後,您可以編寫類型處理程序來將Java對象映射到Oracle對象。

import oracle.sql.ARRAY; 
import oracle.sql.ArrayDescriptor; 
import oracle.sql.STRUCT; 
import oracle.sql.StructDescriptor; 
.... 
public class YourTypeHandler implements TypeHandler 
{ 
.... 
    public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException 
    { 
     List<YourObject> objects = (List<YourObject>) parameter; 

     StructDescriptor structDescriptor = StructDescriptor.createDescriptor("YOUR_OBJECT", ps.getConnection()); 

     STRUCT[] structs = new STRUCT[objects.size()]; 
     for (int index = 0; index < objects.size(); index++) 
     { 
      YourObject pack = packs.get(index); 
      Object[] params = new Object[2]; 
      params[0] = pack.getFieldOne(); 
      params[1] = pack.getFieldTwo(); 
      STRUCT struct = new STRUCT(structDescriptor, ps.getConnection(), params); 
      structs[index] = struct; 
     } 

     ArrayDescriptor desc = ArrayDescriptor.createDescriptor("YOUR_OBJECT_ARRAY", ps.getConnection()); 
     ARRAY oracleArray = new ARRAY(desc, ps.getConnection(), structs); 
     ps.setArray(i, oracleArray); 
    } 
} 

然後調用程序,

call your_proc 
(
#{yourObjects, javaType=Object, jdbcType=ARRAY, jdbcTypeName=YOUR_OBJECT_ARRAY, mode=IN, typeHandler=YourObjectArrayTypeHandler} 
) 
+0

找不到TypeHandler的類/ jar。已經有ojdbc6.jar – aishu

0

安迪·普賴爾的回答是我測試,它真正的作品非常好。但它在類型控制器的錯誤:

call your_proc 
(
#{yourObjects, javaType=Object, jdbcType=ARRAY, jdbcTypeName=YOUR_OBJECT_ARRAY, mode=IN, typeHandler=YourObjectArrayTypeHandler} 
) 

應該是:

call your_proc 
(
#{yourObjects, javaType=Object, jdbcType=ARRAY, jdbcTypeName=YOUR_OBJECT_ARRAY, mode=IN, typeHandler=YourTypeHandler} 
) 

該類型處理器有錯誤,以及:(沒有「包裝」,並沒有在方法的參數中的一些差異我的版本)

@Override 
public void setParameter(PreparedStatement ps, int i, Object parameter, String arg3) throws SQLException { 
    List<YourObject> objects = (List<YourObject>) parameter; 

    StructDescriptor structDescriptor = StructDescriptor.createDescriptor("YOUR_OBJECT", ps.getConnection()); 

    STRUCT[] structs = new STRUCT[objects.size()]; 
    for (int index = 0; index < objects.size(); index++) 
    { 
     YourObject pack = objects.get(index); 
     Object[] params = new Object[2]; 
     params[0] = pack.getFieldOne(); 
     params[1] = pack.getFieldTwo(); 
     STRUCT struct = new STRUCT(structDescriptor, ps.getConnection(), params); 
     structs[index] = struct; 
    } 

    ArrayDescriptor desc = ArrayDescriptor.createDescriptor("YOUR_OBJECT_ARRAY", ps.getConnection()); 
    ARRAY oracleArray = new ARRAY(desc, ps.getConnection(), structs); 
    ps.setArray(i, oracleArray); 
} 

這裏是XML映射的例子:

<parameterMap id="updateHierPersonAssignMap" class="java.util.Map" >      
    <parameter property="p_array" jdbcType="ARRAY" javaType="Object" mode="IN" typeHandler="com.aamtech.ria.model.domain.typehandler.YourTypeHandler"/> 
    </parameterMap> 
    <procedure id="updateHierPersonAssign" parameterMap="updateHierPersonAssignMap" > 
    <![CDATA[ 
     { call ria_am_util_pkg.j_update_hier_person_assign(?) } 
    ]]> 
    </procedure> 

這裏是如何可以從DAO調用它:

public void update(List array) { 
    Map<String, Object> queryParams = new HashMap<String, Object>(); 
    queryParams.put("p_array", array); 
    try { 
     client.update("HashMapResult.updateHierPersonAssign", queryParams); 
    } catch (SQLException e) { 
    } 
} 

我的過程是這樣的(它只是將行插入測試表):

Procedure j_update_hier_person_assign (p_array IN YOUR_OBJECT_ARRAY) is 
    begin 
    FOR i IN 1..p_array.count LOOP 
     --dbms_output.put_line(); 
     insert into test (a) values (p_array(i).field_one); 
    END LOOP; 
    end; 
相關問題