日期:2013-05-14  浏览次数:20485 次


        大凡使用过JDBC连ORACLE的人都会知道这样一个理想:我们需求的库文件classes12.zip存在于$ORACLE_HOME/jdbc/lib目录下(但仍有部分菜鸟每每在论坛上求此库文件,真是辛劳);但很少有人知道ORACLE还为我们预备了使用jdbc的示例,它存在于 $ORACLE_HOME/jdbc/demo/demo.zip 中。
        前一段时间,我学习ORACLE的OOP技术,很受触动。当时我想:JDBC中一定存在某些OO技术以支持它。很久都没有找到合适的例子,最后在ORACLE的安装目录下找到它。真可谓是:踏破铁鞋无觅处,得来全不费时间。

        商定:
        1、如果出现 java.lang.UnsatisfiedLinkError: do_open,则你需求把 DriverManager.getConnection() 方法的 url 修正成 jdbc:oracle:thin:@127.0.0.1:1521:oradb,具体缘由未知;
        2、如果出现 java.sql.SQLException: 不支持的字符集: oracle-character-set-852,则你需求把 nls_charset12.zip加入你的工程中(此文件与 classes12.zip 同目录);

        下面我就把文件夹 amples\oci8\object-samples下的文件做一个详细的功用描述:
        1、PersonObject.java
        这个例子演示了表 people 中存在ADT字段 empid,其类型为 PERSON,而且类型 PERSON中存在ADT字段 home,其类型为 ADDRESS,而且类型 ADDRESS是一个ADT。
        如果使用常规SQL语句,其插入语句与在sql/plus中无异,即:使用结构函数嵌套结构。
        另有一种方法,使用 STRUCT 的结构函数 STRUCT(StructDescriptor, Connection, Object[]) 结构出一个STRUCT对象,即一个ADT对象。同时,如果有嵌套则需求嵌套结构ADT对象。最后通过 PreparedStatement的 setObject方法指定ADT对象即可。
        读取数据时则采用与上述方法相逆的办法:如果是简单类型,则直接读取;如果是ADT,则使用ResultSet的getObject(),再强制转换成STRUCT,然后调用STRUCT的getAttributes()方法取得 Object[] 类型数据,如是递归。

        2、SQLDataExample.java与EmployeeObj.java
        此例与1中类似,也是对ADT的处理,不同的是类型没有嵌套。
        比较而言,2比1的代码简约了很多,不过也是付出了代价:为类型 EMPLOYEE 笼统出一个类EmployeeObj,它实现了SQLData接口,并重写了三个方法(必须的)。
        前台的调用比1中的第二种方法简约了很多,只需求直接使用PreparedStatement的 setObject方法指定ADT对象即可(不过需求指定其类型为OracleTypes.STRUCT)。读取时也可直接使用OracleResultSet的getObject()并强制转换成EmployeeObj对象即可。
        真可谓是:有得必有失!!
        另,此例中有几处需求留意的地方:
        2.1 EmployeeObj.java中的 import oracle.jdbc2.*; 改成 import oracle.jdbc.*; 缘由未知;
        2.2 SQLDataExample.java 中的 Dictionary map = conn.getTypeMap(); 改成 java.util.Map map = conn.getTypeMap(); 缘由:NOTE:  This class(指的是Dictionary) is obsolete. New implementations should implement the Map interface, rather than extendidng this class.(来源:javadoc);
        2.3 SQLDataExample.java 中的 pstmt.executeQuery(); 改成 pstmt.executeUpdate(); 更合理些,由于这是更新而非查询(不改也不会影响功用,只是建议);

        3、CustomDatumExample.java与Employee.java
        此例与2完全相反。不同的是采用了另外一种笼统技术,并实现了接口CustomDatum 与 CustomDatumFactory,并重写了二个方法toDatum()与create()。在前台访问数据时亦有少许不同:采用了OracleResultSet的getCustomDatum()方法并把它强制转换成Employee。从外观上看,2中SQLData接口存在于 java.sql.* 包中;而接口CustomDatum 与 CustomDatumFactory则存在于oracle.sql.*包中,可以认为是Oracle公司对本人产品的专门实现。或许有更高的功用、更小的开销?不过3不如2来得直接,团体认为。

        4、ArrayExample.java
        从文件名可看出,此示例演示的是VARRAY类型。
        同1,插入亦有两种方法。一种可直接使用SQL;另外,可使用OraclePreparedStatement的setARRAY方法,结构ARRAY的过程与结构 STRUCT 无异。数据的读取过程与此相反:先使用OracleResultSet的getARRAY()方法取得ARRAY对象,再调用此对象的getArray()方法并强制转换成对象数组,然后对此数组操作即可。

        5、PersonRef.java与StudentRef.java
        不知是不是ORACLE与我们开玩笑,这两个文件除了类名不同外,其余一切相反。
        这个例子给我们演示的是对象表的概念。对象表的插入与普通表没有任何不同,数据的读取首先体如今其SQL上,需求使用REF函数,然后调用ResultSet的getObject()方法并强制转换成REF对象,再利用此对象的getValue()并转换成STRUCT对象,再利用此对象 的getAttributes