我有一个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;
}