簡體   English   中英

Java SQLData-使用列表/數組強制轉換為用戶對象?

[英]Java SQLData - Cast to user object with a list/array?

我正在學習如何使用SQLData,並且在投射回我的對象​​時遇到問題。

我的Oracle類型看起來像這樣:

CREATE OR REPLACE TYPE activities_t AS OBJECT
(
   list   activity_list_t;
);

CREATE OR REPLACE TYPE activity_list_t AS TABLE OF activity_t;

CREATE OR REPLACE TYPE activity_t AS OBJECT
(
   startDate  DATE;
   endDate    DATE;
);

我的Java看起來像這樣:

public class Activities implements SQLData {
    private String sqlType = "ACTIVITIES_T";
    List<Activity> list;

    // must have default ctor!
    public Activities() {
    }

    public String getSQLTypeName() throws SQLException
    { 
        return sqlType; 
    }

    public List getList() {
        return list;
    }

    public void setList(List list) {
        this.list = list;
    }

    public void readSQL(SQLInput stream, String typeName) throws SQLException 
    {
        Array a = stream.readArray();
        // :(
    }

    public void writeSQL(SQLOutput stream) throws SQLException 
    {
        // stream.writeArray(this.list);
    }
}

我已經在readSQL中嘗試了幾件事,但沒有取得太大的成功-我缺少什么?

我正在使用JDBC調用一個OUT參數為“ activities_t”的PLSQL存儲過程:

Map map = connection.getTypeMap();
map.put("ACTIVITIES_T", Class.forName("Activities"));
connection.setTypeMap(map);

callableStatement = connection.prepareCall("{call GET_ACTIVITIES(?)}");
callableStatement.execute();

謝謝! 史蒂夫

(以上大部分內容都來自內存,因為代碼正在起作用...)

您需要為ACTIVITY_TACTIVITIES_T類型添加一個類型映射。 從您的問題尚不清楚您是否已經完成此操作。

假設您已完成此操作,並創建了一個名為Activity的類,該類也實現了SQLData 一旦你這樣做了,下面應該足以閱讀中的活動列表Activities

    public void readSQL(SQLInput stream, String typeName) throws SQLException {
        Array array = stream.readArray();
        this.list = new ArrayList<Activity>();
        for (Object obj : (Object[])array.getArray()) {
            list.add((Activity)obj);
        }
    }

提示:

  • JDBC API在類型名稱方面區分大小寫。 如果您的類型名稱不完全匹配,則會看到“ Unable to resolve type錯誤。 Oracle將大寫您的類型名稱,除非您在其create語句中用雙引號將該名稱引起來。
  • 如果類型不在默認模式中,則可能需要指定SCHEMA.TYPE_NAME
  • 如果要連接的用戶不是所有者,請記住要grant execute對類型的grant execute
    如果您在程序包上執行過,但沒有執行過類型,則getArray()在嘗試查找類型元數據時將引發異常。

getArray()

我的解決方案與Luke的解決方案基本相同。 但是,我需要在獲取數組時提供類型映射: array.getArray(typeMap)您還可以在Connection上設置默認的類型映射,但這對我不起作用。

調用getArray()將獲得對象類型的數組,即創建的代表activity_tSQLData實現。

這是一個通用函數,您可能會發現它有用:

public static <T> List<T> listFromArray(Array array, Class<T> typeClass) throws SQLException {
    if (array == null) {
        return Collections.emptyList();
    }
    // Java does not allow casting Object[] to T[]
    final Object[] objectArray = (Object[]) array.getArray(getTypeMap());
    List<T> list = new ArrayList<>(objectArray.length);
    for (Object o : objectArray) {
        list.add(typeClass.cast(o));
    }
    return list;
}

writeArray()

弄清楚如何編寫數組令人沮喪,Oracle API需要使用Connection才能創建數組,但是在writeSQL(SQLOutput sqlOutput)上下文中沒有明顯的Connection。 幸運的是, 此博客有一個技巧/技巧來獲取OracleConnection ,我在這里使用了它。

當使用createOracleArray()創建數組時,請為類型名稱而不是對象類型指定列表類型。 activity_list_t

這是用於編寫數組的通用函數。 在您的情況下, listType將為"activity_list_t"並且您將傳遞List<Activity>

public static <T> void writeArrayFromList(SQLOutput sqlOutput, String listType, @Nullable List<T> list) throws SQLException {
    final OracleSQLOutput out = (OracleSQLOutput) sqlOutput;
    OracleConnection conn = (OracleConnection) out.getSTRUCT().getJavaSqlConnection();
    conn.setTypeMap(getTypeMap());  // not needed?
    if (list == null) {
        list = Collections.emptyList();
    }
    final Array array = conn.createOracleArray(listType, list.toArray());
    out.writeArray(array);
}

注意:曾經我以為setTypeMap是必需的,但是現在當我刪除該行時,我的代碼仍然有效,所以我不確定是否有必要。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM