Java SQLData-使用列表/数组强制转换到用户对象?
我正在学习如何使用SQLData,并且在回溯到我的对象时遇到了问题 我的Oracle类型如下所示: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
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区分大小写,当您不使用带引号的标识符时,它会将所有内容转换为大写。