Oracle JDBC读/写自定义集合类型

时间:2014-01-02 18:44:34

标签: java oracle jdbc plsql

我有一个Java对象,它扩展了SQLData - Delivery。我打算在DB中读取和写入一组Delivery对象。我对WRITE部分感到高兴。我想我需要改进READ部分。如何直接将oracle TABLE TYPE映射到Delivery对象列表?

以下代码已更改,以保持此帖子简短。因此,可能存在一些错误,但所有存储过程和代码都很好。我觉得READ部分非常麻烦 - getDeliveriesByDlvryDt()。我该如何改进呢?

// Java code
public class Delivery implements Serializable, SQLData {
    private String custNbr;
    private String dlvryDt;

    (...)

    private String typeName = "DELIVERY_OBJ";
    @Override
    public String getSQLTypeName() throws SQLException {
        return typeName;
    }
    @Override
    public void readSQL(SQLInput stream, String typeName) throws SQLException {
        this.typeName = typeName; 
        custNbr = stream.readString();
        dlvryDt = stream.readString();

    }
    @Override
    public void writeSQL(SQLOutput stream) throws SQLException {

        try{
            stream.writeString(custNbr);
            stream.writeString(dlvryDt);
        }catch(Exception e){
            logError(e.getMessage());
        }
    }
}


-- PL/SQL code
CREATE OR REPLACE TYPE DELIVERY_OBJ AS OBJECT
(   CUST_NBR         NUMBER,
    DLVRY_DT         NUMBER,
);

CREATE OR REPLACE TYPE DELIVERY_TBL IS TABLE OF DELIVERY_OBJ;

PROCEDURE delivery_upsert_1(
  p_deliveryList      IN DELIVERY_TBL)
IS
BEGIN
  MERGE INTO DELIVERY D
  USING (SELECT * FROM TABLE(p_deliveryList)) DL
  ON (D.CUST_NBR = DL.CUST_NBR and D.DLVRY_DT = DL.DLVRY_DT)
  WHEN NOT MATCHED THEN INSERT
      (CUST_NBR, DLVRY_DT)
      VALUES (DL.CUST_NBR, DL.DLVRY_DT)
  WHEN MATCHED THEN UPDATE
      SET D.CUST_NBR = DL.CUST_NBR, D.DLVRY_DT = DL.DLVRY_DT;
END delivery_upsert_1;

PROCEDURE get_delivery_by_dlvry_dt_3(
  p_DLVRY_DT           IN DELIVERY.DLVRY_DT%TYPE,
  p_deliveryList     OUT DELIVERY_TBL)
IS
BEGIN
  SELECT DELIVERY_OBJ(D.CUST_NBR, D.DLVRY_DT) BULK COLLECT into p_deliveryList
  FROM DELIVERY D
END get_delivery_by_dlvry_dt_3;


// Java code
public void upsertDeliveries(Delivery[] deliveries){

    String query = "{call"+SCHEMA+"."+PACKAGE+".delivery_upsert_1(?)}";
    CallableStatement cs = null;
    Connection con = null;

    try{
        //get connection
        ArrayDescriptor arrayDesc = ArrayDescriptor.createDescriptor("WMT_DELIVERY_TBL", con);
        ARRAY arrayUpdate = new ARRAY(arrayDesc, con,(Object[])deliveries);

        cs = con.prepareCall(query);
        cs.setObject(1, arrayUpdate);
        cs.execute();
    }catch(Exception e){
        logError(extractStackTrace(e));
    }finally{
        try{
            cs.close();
        }catch(Exception e){
            logError(e.getMessage());
        }
    }
}



public DBDelivery[] getDeliveriesByDlvryDt(String dlvryDt) {
    String query = "{call"+SCHEMA+"."+PACKAGE+".get_delivery_by_dlvry_dt_3(?,?)}";
    CallableStatement cs = null;
    Connection con = null;

    final String typeName = "DELIVERY_OBJ";
  final String typeTableName = "DELIVERY_TBL";

    try{
        //got the connection    
        cs = con.prepareCall(query);
        cs.setString(1, userName);
        cs.registerOutParameter(2, Types.ARRAY, typeTableName);
        cs.execute();

        Object[] data = (Object[]) ((Array) cs.getObject(2)).getArray();
        for(Object tmp : data) {
           Struct row = (Struct) tmp;
           System.out.println(row);                                            
        }

    }catch(Exception e){
        logError(extractStackTrace(e));
    }finally{
        try{
            cs.close();
        }catch(Exception e){
            logError(e.getMessage());
        }
    }
    return null;
}

更新1 - 我的getDeliveriesByDlvryDt的最终版本:

public DBDelivery[] getDeliveriesByDlvryDt(String dlvryDt) {
    String query = "{call"+SCHEMA+"."+PACKAGE+".get_delivery_by_dlvry_dt_3(?,?)}";
    CallableStatement cs = null;
    Connection con = null;

    final String typeName = "DELIVERY_OBJ";
  final String typeTableName = "DELIVERY_TBL";

    try{
        //got the connection    
        Map typeMap = conn.getTypeMap();
        conn.setTypeMap(typeMap);
        typeMap.put(typeName, Class.forName(Delivery.class.getName())); 

        cs = con.prepareCall(query);
        cs.setString(1, userName);
        cs.registerOutParameter(2, Types.ARRAY, typeTableName);
        cs.execute();

        List<Delivery> deliveries = new ArrayList<Delivery>();
        Object[] data = (Object[]) ((Array) cs.getObject(2)).getArray();
        for(Object tmp : data) {
            deliveries.add((Delivery)tmp);
        }
    }catch(Exception e){
        logError(extractStackTrace(e));
    }finally{
        try{
            cs.close();
        }catch(Exception e){
            logError(e.getMessage());
        }
    }
    return null;
}

0 个答案:

没有答案