[英]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_T
和ACTIVITIES_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);
}
}
提示:
Unable to resolve type
錯誤。 Oracle將大寫您的類型名稱,除非您在其create語句中用雙引號將該名稱引起來。 SCHEMA.TYPE_NAME
。 grant execute
對類型的grant execute
。 getArray()
在嘗試查找類型元數據時將引發異常。 getArray()
我的解決方案與Luke的解決方案基本相同。 但是,我需要在獲取數組時提供類型映射: array.getArray(typeMap)
您還可以在Connection上設置默認的類型映射,但這對我不起作用。
調用getArray()
將獲得對象類型的數組,即創建的代表activity_t
的SQLData
實現。
這是一個通用函數,您可能會發現它有用:
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.