2012-10-04 14 views
7

मैं थोड़ी देर के लिए यह गुगल रहा हूं और किसी भी वास्तविक उत्तर नहीं लग रहा है।MyBatis का उपयोग करते हुए ओरेकल संग्रहीत प्रक्रिया में ऑब्जेक्ट्स की जावा सूची कैसे पास करें?

मेरे पास ओरेकल संग्रहीत प्रक्रिया है जिसमें कई पैरामीटर हैं जिनमें एक प्रकार है जो तालिका पंक्ति प्रकार की तालिका है। उदाहरण के लिए:

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; 

ओरेकल प्रक्रिया:

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

जावा तरफ, मैं से प्रत्येक का प्रतिनिधित्व वस्तुओं के 3 इसी सूचियाँ है जावा में आबादी वाले पैरामीटर। क्या इस परिदृश्य में MyBatis का उपयोग कर ओरेकल प्रक्रिया को कॉल करना संभव है?

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

ऑब्जेक्ट्स स्वयं स्ट्रिंग और इंटीजर गुणों और उनके संबंधित गेटर्स और सेटर्स के साथ सरल वीओ हैं।

मुझे सच में यकीन नहीं है कि कैसे आगे बढ़ना है। क्या मुझे किसी भी तरह जावा ऑब्जेक्ट सूचियों को ओरेकल प्रकारों में मैप करने की ज़रूरत है?

अग्रिम धन्यवाद।

उत्तर

7

मैं यह नहीं बता सकता कि आप पहले से ही हैं या नहीं, लेकिन आपको ओरेकल ऑब्जेक्ट्स को परिभाषित करने की आवश्यकता होगी।

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

फिर आप जावा ऑब्जेक्ट्स को ओरेकल ऑब्जेक्ट्स पर मैप करने के लिए टाइप हैंडलर लिख सकते हैं।

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 के लिए कक्षा/जार। पहले से ही ojdbc6.jar है – aishu

0

एंडी प्रायर का जवाब बहुत अच्छा मैं यह परीक्षण किया है और यह वास्तव में काम करता है। लेकिन यह typeHandler में कोई त्रुटि है:

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

TypeHandler एक त्रुटि के साथ-साथ हैं: (कोई "पैक" और वहाँ में विधि मानकों में कुछ अंतर है

<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> 
: मेरे संस्करण)

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

और यहाँ एक्सएमएल मानचित्रण के लिए एक उदाहरण है

और यहाँ है कि आप इसे कैसे डीएओ से कॉल कर सकते हैं:

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; 
संबंधित मुद्दे