Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SQLData-使用列表/数组强制转换到用户对象?_Java_Oracle_Jdbc_Types_Mapping - Fatal编程技术网

Java SQLData-使用列表/数组强制转换到用户对象?

Java SQLData-使用列表/数组强制转换到用户对象?,java,oracle,jdbc,types,mapping,Java,Oracle,Jdbc,Types,Mapping,我正在学习如何使用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 ( startDat

我正在学习如何使用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;
);
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);
    }
}
我的Java如下所示:

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;
);
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);
    }
}
谢谢! 史蒂夫


(以上大部分内容都来自内存,因为代码正在工作…

您需要为类型
活动添加一个类型映射,以及为
活动添加一个类型映射。你的问题不清楚你是否已经这样做了

假设您已经完成了这项工作,并创建了一个名为
Activity
的类,该类还实现了
SQLData
。完成此操作后,以下内容应足以阅读
活动
中的活动列表:

    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);
        }
    }
public void readSQL(SQLInput stream,String typeName)抛出SQLException{
数组=stream.readArray();
this.list=new ArrayList();
对于(Object obj:(Object[])array.getArray()){
列表。添加((活动)obj);
}
}
提示:

  • JDBCAPI对于类型名是区分大小写的;如果您的类型名称不完全匹配,您将看到一个
    无法解析类型的错误。除非在create语句中双引号引用类型名称,否则Oracle将使用大写形式
  • 您可能需要指定
    架构。如果类型不在默认架构中,请键入\u NAME
  • 如果您连接的用户不是所有者,请记住对类型授予执行权限。
    如果您对包执行了execute,但没有对类型执行,
    getArray()
    在尝试查找类型元数据时将引发异常
getArray()

我的解决方案与卢克的基本相同。但是,在获取数组时,我需要提供一个类型映射:
array.getArray(typeMap)
您还可以在连接上设置默认类型映射,但这对我不起作用

调用
getArray()
时,您会得到一个对象类型的数组,即您创建的表示
活动的
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;
}

注意:有一次我认为需要
setTypeMap
,但现在当我删除这一行时,我的代码仍然有效,所以我不确定是否有必要这样做。

谢谢,一旦我发现我缺少了另一个类型映射,我就得到了类似的结果:)谢谢你的回答,但是writeSQL实现呢?我找不到将列表转换为java.sql.Array的正确方法。@DmitryAvgustis:怎么样?Oracle区分大小写,不区分大小写-默认行为是将所有不带引号的标识符转换为大写(因此它似乎不区分大小写)但您可以在标识符周围使用双引号来抑制这种行为,并且它将尊重标识符的大小写敏感性。编辑以澄清。如果我将一个类型名小写,我会得到这个错误代码[17060];无法构造描述符:无法解析类型“MYSCHEMA.mytype”;嵌套异常是java.sql.SQLException:无法构造描述符:无法解析类型“MYSCHEMA.mytype
如果您执行
创建类型MYSCHEMA。“mytype”在Oracle中是…
,那么您将得到一个类型,其中该类型的标识符区分大小写(小写)。如果执行
创建类型MYSCHEMA.mytype是…
(不带引号)然后您将得到一个类型,其中该类型的标识符是
MYTYPE
(大写),就像Oracle在幕后将不带引号的标识符转换为大写一样。您的开场白是“即使Oracle不区分大小写”“不正确-当您使用带引号的标识符时,Oracle区分大小写,当您不使用带引号的标识符时,它会将所有内容转换为大写。