`
lazybird86
  • 浏览: 2873 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
社区版块
存档分类
最新评论

JDBC获取和操纵Oracle集合的方法

阅读更多

      上周需要在ibatis里调用oracle的一个存储过程,这个存储过程有一个参数是index table,需要实现TypeHandler或者TypeHandlerCallback。上网查g.cn一下,发现没有多少文章介绍,只有少数不全的,倒是有一篇鬼佬写的,比较详细,但只介绍到nested table的情况。Oracle里面三种集合类型,分别是variable array、nested table、index table,前两种已经有例子,但index table呢,如何实现?这让挺伤脑筋的!很自然的想到,看JDBC规范,发现没有相应扩展类型的介绍。想想,各大数据库厂商,都应该是有自己的JDBC实现和使用文档的。于是,上Oracle官网,下了好几篇文档。于是,在JDBC 3.0和4.0规范,Oracle8i、Oracle9i和Oracle10g的JDBC开发指引文档下,总算搞清楚了。既然费劲找到原因了,不写篇东西记下,对不起自己!加上年纪大了,记性不好,记下以后好翻查,而且自己一直说想写写技术文章的,种种原因,导致我这么多废话的记下这篇东西。
     首先,你如果是使用JDK6.0的话,那么你很幸运。JDK 6.0支持JDBC 4.0,这让你在这个问题面前,不用多几条白头发。如果是JDK5.0或者之前的版本,像我公司使用的是1.4,那么你就纠结了,需要使用Oracle的JDBC扩展去实现,像index table这种情况,还要依赖于你使用的Oracle JDBC Driver。相信很多时候,我们都是纠结的。当然,可能还有其他方法处理,因为我自己本身这类数据库应用开发经验很少。
     1. 通过Oracle的JDBC扩展实现获取和操纵Oracle集合
     不管是variable array或者nested table,在Java对应的实现,都是为JDBC里的Array类型,这两种类型后面补充。要注意,只能处理命名的集合类型。
     1.1确定你使用的Oracle数据库的版本
     你的数据库版本决定你能否操纵的集合类型。在Oracle8i的文档里,只有对Array类型进行说明,标题为“Working with Arrays”,显示没有集合这个概念。而Oracle9i的文档是,有专门的“Working with Oracle Collections”。
当然,我没有细看,文档查阅的也有限。在有限的了解下,得出只有Oracle9i以上的情况下,才有可能对index table类型支持。
     1.2其次是Driver的版本
     必须是JDBC OCI Driver才能支持。这部分文档在JDBC OCI Extensions里有介绍。支持常用的PL SQL的整数和字符串类型,类型列表文档也有列出。
     1.3使用OCI Driver下内置方法
     前面第1、2点满足后,使用OraclePreparedStatement和OracleCallableStatement内置方法支持,如下:
    

setPlsqlIndexTable()
registerIndexTableOutParameter()
getOraclePlsqlIndexTable()
getPlsqlIndexTable()

 

    把文档里的例子贴出来,看看也大概知道怎么使用。
    1.3.1 对于IN参数

    

// Prepare the statement
OracleCallableStatement procin = (OracleCallableStatement)
conn.prepareCall ("begin procin (?); end;");
// index-by table bind value
int[] values = { 1, 2, 3 };
// maximum length of the index-by table bind value. This
// value defines the maximum possible "currentLen" for batch
// updates. For standalone binds, "maxLen" should be the
// same as "currentLen".
int maxLen = values.length;
// actual size of the index-by table bind value
int currentLen = values.length;
// index-by table element type
int elemSqlType = OracleTypes.NUMBER;
// index-by table element length in case the element type
// is CHAR, VARCHAR or RAW. This value is ignored for other
// types.
int elemMaxLen = 0;
// set the value
procin.setPlsqlIndexTable (1, values,
maxLen, currentLen,
elemSqlType, elemMaxLen);
// execute the call
procin.execute ();

 
    1.3.2 对于OUT参数

    

// maximum length of the index-by table value. This
// value defines the maximum table size to be returned.
int maxLen = 10;
// index-by table element type
int elemSqlType = OracleTypes.NUMBER;
// index-by table element length in case the element type
// is CHAR, VARCHAR or RAW. This value is ignored for other
// types
int elemMaxLen = 0;
// register the return value
funcnone.registerIndexTableOutParameter
(1, maxLen, elemSqlType, elemMaxLen);

     
    1.3.3 获取OUT参数的值
    有三个方法能获取index table(OUT参数)中的值,如下:
   (1) Object getPlsqlIndexTable (int paramIndex)
    该方法返回Object类型,强制类型转换为JDBC默认对应的Java类型。

   

// access the value using JDBC default mapping
BigDecimal[] values =
(BigDecimal[])funcnone.getPlsqlIndexTable (1);

 
   (2) Datum[] getOraclePlsqlIndexTable (int paramIndex)
    该方法返回Oracel JDBC的类型,oracle.sql.Datum,使用该类获取相应类型的值。

   

// access the value using Oracle JDBC mapping
Datum[] outvalues = funcnone.getOraclePlsqlIndexTable (1);
// print the elements
for (int i=0; i<outvalues.length; i++)
System.out.println (outvalues[i].intValue());

 
   (3) Object getPlsqlIndexTable (int paramIndex, Class primitiveType)
    该方法要指定对应的Java类型。

   

// access the value as a Java primitive array.
int[] values = (int[])
funcnone.getPlsqlIndexTable (1, java.lang.Integer.TYPE);

 
    2.  补充:variable array、nested table的操纵方法
    2.1 创建oracle.sql.ARRAY对象
    首先,需要 创建oracle.sql.ArrayDescriptor对象,该类型是用来描述Array类型的,在构造函数中需要指名类型名称。

    

ArrayDescriptor arraydesc = ArrayDescriptor.createDescriptor
(sql_type_name, connection);

 
    sql_type_name指定使用集合类型,connection使用当前连接。
    接着,就可以使用这个ArrayDescriptor对象,来创建对应的oracle.sql.ARRAY对象。

   

ARRAY array = new ARRAY(arraydesc, connection, elements);

 
    elements指定集合包含的值,可以是Java基本类型或者对象数组。

    直接看文档的示例,可能更清楚,如下。

   

Connection conn = ...; // make a JDBC connection
// create the collection types
Statement stmt = conn.createStatement ();
stmt.execute ("CREATE TYPE varray1 AS VARRAY(10) OF NUMBER(12, 2)"); // one
// layer
stmt.execute ("CREATE TYPE varray2 AS VARRAY(10) OF varray1"); // two layers
stmt.execute ("CREATE TYPE varray3 AS VARRAY(10) OF varray2"); // three layers
stmt.execute ("CREATE TABLE tab2 (col1 index, col2 value)");
stmt.close ();
// obtain a type descriptor of "SCOTT.VARRAY3"
ArrayDescriptor desc = ArrayDescriptor.createDescriptor("SCOTT.VARRAY3", conn);
// prepare the multi level collection elements as a nested Java array
int[][][] elems = { {{1}, {1, 2}}, {{2}, {2, 3}}, {{3}, {3, 4}} };
// create the ARRAY by calling the constructor
ARRAY array3 = new ARRAY (desc, conn, elems);
// some operations
...
// close the database connection
conn.close();

 
    2.2 获取Array对象的值
    主要有三个方法

   

getArray()
getOracleArray()
getResultSet()

 
    不用多说,直接上文档示例代码。

   

stmt.execute ("CREATE TYPE num_varray AS VARRAY(10) OF NUMBER(12, 2)");
stmt.execute ("CREATE TABLE varray_table (col1 num_varray)");
stmt.execute ("INSERT INTO varray_table VALUES (num_varray(100, 200))");
ResultSet rs = stmt.executeQuery("SELECT * FROM varray_table");
ARRAY my_array = ((OracleResultSet)rs).getARRAY(1);
// return the SQL type names, integer codes,
// and lengths of the columns
System.out.println ("Array is of type " + array.getSQLTypeName());
System.out.println ("Array element is of typecode " + array.getBaseType());
System.out.println ("Array is of length " + array.length());
// get Array elements
BigDecimal[] values = (BigDecimal[]) my_array.getArray();
for (int i=0; i<values.length; i++)
{
BigDecimal out_value = (BigDecimal) values[i];
System.out.println(">> index " + i + " = " + out_value.intValue());
}
 ResultSet rset = my_array.getResultSet();
while (rset.next())
{
// The first column contains the element index and the
// second column contains the element value
System.out.println(">> index " + rset.getInt(1)+" = " + rset.getInt(2));
}

 
    2.3 使用Array对象作为过程函数的参数
    很简单,直接使用OraclePreparedStatement.setARRAY或者OracleCallableStatement.registerOutParameter传入。

 

后记
     这篇东西上年就写了一点,回家过年,闲着没事就写完了。回来电脑又坏了,直到今天才想起贴出来。不是什么大作,记下东西,以前没有这习惯总结,现在争取想有空写点,练练笔头。

 

参考:
     Oracle JDBC JavaDoc
     Oracle9i JDBC Developer’s Guide and Reference
     Oracle8i JDBC Developer’s Guide and Reference

分享到:
评论

相关推荐

    java复习题,jdbc,DAO模式,oracle复习题

    复习Oracle需要熟悉SQL语法,包括DML(数据操纵语言)和DDL(数据定义语言)。此外,还要了解Oracle的数据类型、约束条件、分区策略、性能优化技术,如索引、物化视图、表空间管理等。 这些知识点的结合,意味着你...

    Oracle11i中文帮助文档4

    这个文档集合通常被分割成多个部分,以方便下载和管理,例如本例中的"Oracle11i-1.rar"至"Oracle11i-4.rar"。这些文档主要以CHM(Compiled Help Manual)格式存在,这是一种Windows平台下常见的帮助文件格式,集成了...

    jstl el servlet jdbc 实例

    **JSTL、EL、Servlet和JDBC是Java Web开发中的关键组件,它们共同构建了动态网站应用程序的基础。本文将详细解析这些技术及其在实际应用中的实例。** **JSTL(JavaServer Pages Standard Tag Library)** 是一组预...

    JDBC实验手册.doc

    T-SQL 语言是对数据库进行管理和操作的第四代语言,主要包括数据定义语言(DDL)、数据操纵语言(DML)、数据控制语言(DCL)和系统存储过程(System Stored Procedure)。T-SQL 语言是用于管理和操作数据库的主要...

    Oracle 从入门到精通视频教程(11G版本)(ppt)

    《Oracle 从入门到精通》中的视频教程和PPT资料。 Oracle 11G从入门到精通视频的PPT 第1章-Oracle 11g数据库简介 认识Oracle 11g 回忆Oracle的产品版本 学习Oracle 11g的新特性 第2章-Oracle 11g的安装与测试...

    oracleobject设计毕业设计论文完整版设计论文.doc

    在 Java 端,我们可以使用 OracleJPublisher 生成相应 Java 类 TradeObject,TradeObjectRef 等与数据库对象一一对应的类,然后使用 JavaJDBC 的操纵这些类以 OracleObject 的方式进行调用。 ParamValuePairList 和...

    oracle相关文档

    数据库实例是Oracle运行时的内存结构和后台进程的集合,而表空间是存储数据的逻辑单位。数据块则是数据库在磁盘上的最小存储单元。用户和权限定义了不同用户对数据库资源的访问控制。 "导出数据库.txt"涉及的是...

    jdbc操作文档,数据库基本操作文档集合

    9.在……和……之间 (between and) select 字段名 from 表名 where 要判断的字段名 between 数值 and 数值; 10.in (相当于or) not in(相当于and) select 字段名 from 表名 where 字段名 in(数值,数值); select ...

    Oracle10g.chm 中文版 帮助文档

    Oracle10g.chm中文版帮助文档是Oracle数据库系统用户的重要参考资料,它包含了关于Oracle10g数据库管理系统的所有核心功能、API(应用程序编程接口)以及详细的使用指南。Oracle数据库是全球广泛使用的大型关系型...

    经典的ORACLE查询语句教学资料

    首先,Oracle SQL是Oracle数据库系统中的数据查询和操纵语言。它允许用户检索、更新、插入和删除数据库中的数据,以及创建和修改数据库结构。学习Oracle SQL的基础包括了解DML(Data Manipulation Language)语句如...

    oracle课件.rar

    "基于Oracle的应用开发"则会探讨如何将Oracle与各种编程语言(如Java、C#)集成,实现应用程序与数据库的交互,以及Oracle提供的API和JDBC驱动的使用。 这个课件集合提供了全面的Oracle学习资源,无论你是初学者...

    MySQL和JDBC.pdf

    DBMS的主要功能包括数据定义、数据操纵、数据控制、数据安全和完整性。DBMS可以是一个单独的程序,也可以是一组相关程序的集合。 JDBC(Java Database Connectivity)是一个Java API,它定义了Java程序如何与数据库...

    用OCI接口操作Oracle数据库详细说明

    OCI作为Oracle数据库的核心API之一,提供了强大而灵活的功能集合,适用于需要高性能和高灵活性的Oracle数据库应用程序开发。通过对OCI的学习和掌握,开发者可以更好地利用Oracle数据库的强大功能,提高应用程序的...

    数据库基础与JDBC编程技术

    - 可以通过`getString()`、`getInt()`等方法获取结果集中的数据。 - **处理查询到的信息** - 通常使用while循环遍历结果集,逐条处理每条记录。 #### 第六讲 使用PreparedStatement预处理SQL语句 - **...

    Oracle 课件

    本课件集合涵盖了Oracle数据库系统的基础到高级概念,旨在帮助学习者全面理解和掌握Oracle的相关知识。 首先,让我们从"oracle1-概述"开始。这部分内容可能涉及Oracle数据库的基本概念,包括它的历史、主要功能、...

    大学毕业论文---oracleobject设计.doc

    OracleObject 允许用户定义自己的数据类型,这使得在存储过程中可以充分利用面向对象的特性,如属性和方法。例如,通过定义一个名为 INSERT_TRADE 的保存过程,接收 Trade_Object 参数,可以像操作 Java 对象一样...

    Oracle基础教程.pptx

    安装Oracle数据库时,需要区分不同类型的安装介质,例如客户端(client)用于与数据库服务器通信,clusterware是集群环境的必备组件,companion包含高级应用组件,database是核心的数据库服务器,Gateways用于访问...

    oracle课件适合初学者

    10. **数据库连接与应用开发**:理解各种数据库连接方式,如ODBC、JDBC、Oracle Instant Client等,以及如何在不同编程语言中与Oracle数据库交互。 通过这个Oracle课件,你将逐步深入Oracle数据库的核心概念和技术...

Global site tag (gtag.js) - Google Analytics