`

Oracle 中Java 对象与PL/SQL类型的映射及使用(转)

 
阅读更多

 

一、Jpublisher概述

Oracle JPublisher是一个用于在Java和SQL之间转换和交换结构化对象数据的工具,它还可以访问其他的数据库资源,如PL/SQL包和Java存储过程。它生成Java类来表示数据库实体,如SQL对象和操作、PL/SQL包和过程以及服务器端Java类。你可以通过JDBC在你的Java客户端、servlet、JavaServer Pages (jsp)、Enterprise JavaBeans (EJB)和Web服务中使用这些生成的类。
  
  JPublisher 可以生成表示以下数据库实体的类:
  
  用户定义的SQL对象类型。对于每个对象类型,JPublisher为表示该对象的类生成一个type.java文件。它提供访问程序方法,用以获取和设置该对象类型的每个属性。还有,如果你的对象类型包含了作为存储过程而实现的方法,则JPublisher将生成封装器方法在对象实例上调用这些方法。
  
  对象引用类型(REF 类型)。 对于一个SQL对象引用类型,JPublisher生成一个typeRef.java文件来建立该Java对象类型的引用模型。它包括通过一个对象引用来访问实际的对象值的方法。
  
  用户定义的SQL集合类型。对于每个集合类型,JPublisher为表示该集合的类生成一个type.java文件。对于嵌套的数据表,生成的类具有作为整个数组来获取和设置嵌套的数据表的一些方法,以及用于获取和设置该数据表中各个元素的一些方法。
  
  用户定义的OPAQUE类型。每当JPublisher遇到一个没有提供其相应类型的SQL OPAQUE类型时,它都会生成一个type.java文件来发布一个Java封装器类。OPAQUE的有效负荷以字节数组(byte array)来表示,可以从生成的封装器的子类中进行处理。
  
  PL/SQL BOOLEAN PL/SQL BOOLEAN被映射到Java Boolean类型。这要求有SYS.SQLJUTL包,该包是由数据库(JPublisher生成的代码要在其中运行)中的sqljutil.sql脚本来安装的。这个脚本默认安装在Oracle Database 10g中。
  
  PL/SQL RECORD和TABLE类型。对于RECORD和TABLE类型,JPublisher生成相应的SQL对象(对于RECORD类型)或SQL VARRAY类型(对于TABLE类型),以及用于在PL/SQL和SQL类型之间进行映射的转换函数。
  
  PL/SQL INDEXED-BY数据表。如果你使用Oracle Database 10g 的JDBC Oracle Call Interface (OCI)驱动程序并且需要发布已有索引的标量数据表,那么你可以直接在Java和这些类型(以Java数组表示)之间进行映射。

二、创建PL/SQL类型与生成Java 对象



--创建Person对象
CREATE OR REPLACE TYPE Person AS OBJECT
(
       p_code 
VARCHAR2(32),
       p_name 
VARCHAR2(16),
       p_age 
NUMBER,
       p_birthday DATE
);


--创建对象表personTable 
CREATE TABLE personTable OF person;


--创建表数组
CREATE OR REPLACE TYPE person_table_type IS TABLE OF Person;

使用Jpublisher 生成java对象,运行createOraObj.bat



createOraObj.bat

SET ORACLE_HOME=C:oracleora92
SET JDBC_LIB=%ORACLE_HOME%jdbclib
SET SQLJ_EXE_HOME=%ORACLE_HOME%bin
SET SQLJ_LIB=%ORACLE_HOME%sqljlib
SET PATH=%PATH%;%SQLJ_EXE_HOME%
SET CLASSPATH=%SQLJ_LIB%translator.jar;%SQLJ_LIB%translator.zip;%SQLJ_LIB%runtime12ee.jar;%SQLJ_LIB%runtime12ee.zip;%JDBC_LIB%classes12.zip;%JDBC_LIB%classes12.jar;%JDBC_LIB%nls_charset12.jar;%JDBC_LIB%nls_charset12.zip;%JDBC_LIB%ojdbc14.jar;%CLASSPATH%
jpub -user
=soft1/soft1 -sql=PERSON_TABLE_TYPE:com.baker.object.PersonTableType -url=jdbc:oracle:thin:@192.168.0.128:1521:pbcuser

运行以上bat后将在当前目录下生成三个java 源文件:Person.java、PersonRef.java、PersonTableType.java

 

三、以PersonTableType作为输入参数的形式调用存储过程



--创建存储过程
CREATE OR REPLACE PROCEDURE testInPersons(persons IN person_table_type) IS
BEGIN
   FORALL i 
IN persons.FIRST .. persons.COUNT
      
INSERT INTO persontable VALUES (persons(i));
   
COMMIT;
END testinpersons;

 



//JDBC调用示例
 OracleCallableStatement cstmt = (OracleCallableStatement) con
         .prepareCall(
"{call testInPersons(?)}");
        
         Person p1 
= new Person();
         p1.setPCode(
"我的身份证11");
         p1.setPName(
"侯廷文11");
         p1.setPAge(
new BigDecimal(44));
         p1.setPBirthday(
new Timestamp(new java.util.Date().getTime()));
        
         Person p2 
= new Person();
         p2.setPCode(
"我的身份证22");
         p2.setPName(
"侯廷文22");
         p2.setPAge(
new BigDecimal(45));
         p2.setPBirthday(
new Timestamp(new java.util.Date().getTime()));
                
         PersonTableType persons
=new PersonTableType();
         persons.setArray(
new Person[]{p1,p2});

         cstmt.setORAData(
1, persons);
         cstmt.execute();

 

四、以PersonTableType作为输出参数的形式调用存储过程



--创建存储过程
CREATE OR REPLACE PROCEDURE testTableOfObject(v_table OUT person_table_type) IS
BEGIN
   v_table :
= person_table_type();
   
FOR i IN 1 .. 5 LOOP
      v_table.EXTEND;
      v_table(i) :
= NEW person(''45212319880810435'' || i,
                               
''侯廷文'' || i,
                               
20 + i,
                               to_date(
''1985-08-1'' || i, ''YYYY-MM-DD''));
   
END LOOP;
END testtableofobject;

 



//JDBC调用示例
OracleCallableStatement cstmt = (OracleCallableStatement) con
                .prepareCall(
"{call testtableofobject(?)}");
        cstmt.registerOutParameter(
1, OracleTypes.ARRAY, "person_table_type"
                .toUpperCase());
        cstmt.execute();
        PersonTableType personCollection 
= (PersonTableType) cstmt.getORAData(
                
1, PersonTableType.getORADataFactory());
        Person[] persons 
= personCollection.getArray();
        
for (int i = 0; i < persons.length; i++) {
            System.out.print(i 
+ "");
            System.out.print(persons[i].getPCode() 
+ " ");
            System.out.print(persons[i].getPName() 
+ " ");
            System.out.print(persons[i].getPAge() 
+ " ");
            System.out.print(persons[i].getPBirthday() 
+ " ");
            System.out.println();
        }

 



输出结果:
0:    452123198808104351    侯廷文1    21    1985-08-11 00:00:00.0    
1:    452123198808104352    侯廷文2    22    1985-08-12 00:00:00.0    
2:    452123198808104353    侯廷文3    23    1985-08-13 00:00:00.0    
3:    452123198808104354    侯廷文4    24    1985-08-14 00:00:00.0    
4:    452123198808104355    侯廷文5    25    1985-08-15 00:00:00.0    

 

五、附上生成的Java对象源文件

 



//com.baker.object.Person.java

package com.baker.object;

import java.sql.SQLException;
import java.sql.Connection;
import oracle.jdbc.OracleTypes;
import oracle.sql.ORAData;
import oracle.sql.ORADataFactory;
import oracle.sql.Datum;
import oracle.sql.STRUCT;
import oracle.jpub.runtime.MutableStruct;

public class Person implements ORAData, ORADataFactory {
    
public static final String _SQL_NAME = "SOFT1.PERSON";

    
public static final int _SQL_TYPECODE = OracleTypes.STRUCT;

    
protected MutableStruct _struct;

    
private static int[] _sqlType = 1212291 };

    
private static ORADataFactory[] _factory = new ORADataFactory[4];

    
protected static final Person _PersonFactory = new Person(false);

    
public static ORADataFactory getORADataFactory() {
        
return _PersonFactory;
    }


    
/* constructor */
    
protected Person(boolean init) {
        
if (init)
            _struct 
= new MutableStruct(new Object[4], _sqlType, _factory);
    }


    
public Person() {
        
this(true);
    }


    
public Person(String pCode, String pName, java.math.BigDecimal pAge,
            java.sql.Timestamp pBirthday) 
throws SQLException {
        
this(true);
        setPCode(pCode);
        setPName(pName);
        setPAge(pAge);
        setPBirthday(pBirthday);
    }


    
/* ORAData interface */
    
public Datum toDatum(Connection c) throws SQLException {
        
return _struct.toDatum(c, _SQL_NAME);
    }


    
/* ORADataFactory interface */
    
public ORAData create(Datum d, int sqlType) throws SQLException {
        
return create(null, d, sqlType);
    }


    
protected ORAData create(Person o, Datum d, int sqlType)
            
throws SQLException {
        
if (d == null)
            
return null;
        
if (o == null)
            o 
= new Person(false);
        o._struct 
= new MutableStruct((STRUCT) d, _sqlType, _factory);
        
return o;
    }


    
/* accessor methods */
    
public String getPCode() throws SQLException {
        
return (String) _struct.getAttribute(0);
    }


    
public void setPCode(String pCode) throws SQLException {
        _struct.setAttribute(
0, pCode);
    }


    
public String getPName() throws SQLException {
        
return (String) _struct.getAttribute(1);
    }


    
public void setPName(String pName) throws SQLException {
        _struct.setAttribute(
1, pName);
    }


    
public java.math.BigDecimal getPAge() throws SQLException {
        
return (java.math.BigDecimal) _struct.getAttribute(2);
    }


    
public void setPAge(java.math.BigDecimal pAge) throws SQLException {
        _struct.setAttribute(
2, pAge);
    }


    
public java.sql.Timestamp getPBirthday() throws SQLException {
        
return (java.sql.Timestamp) _struct.getAttribute(3);
    }


    
public void setPBirthday(java.sql.Timestamp pBirthday) throws SQLException {
        _struct.setAttribute(
3, pBirthday);
    }


}

 



//com.baker.object.PersonRef.java

package com.baker.object;

import java.sql.SQLException;
import java.sql.Connection;
import oracle.jdbc.OracleTypes;
import oracle.sql.ORAData;
import oracle.sql.ORADataFactory;
import oracle.sql.Datum;
import oracle.sql.REF;
import oracle.sql.STRUCT;

public class PersonRef implements ORAData, ORADataFactory {
    
public static final String _SQL_BASETYPE = "SOFT1.PERSON";

    
public static final int _SQL_TYPECODE = OracleTypes.REF;

    REF _ref;

    
private static final PersonRef _PersonRefFactory = new PersonRef();

    
public static ORADataFactory getORADataFactory() {
        
return _PersonRefFactory;
    }


    
/* constructor */
    
public PersonRef() {
    }


    
/* ORAData interface */
    
public Datum toDatum(Connection c) throws SQLException {
        
return _ref;
    }


    
/* ORADataFactory interface */
    
public ORAData create(Datum d, int sqlType) throws SQLException {
        
if (d == null)
            
return null;
        PersonRef r 
= new PersonRef();
        r._ref 
= (REF) d;
        
return r;
    }


    
public static PersonRef cast(ORAData o) throws SQLException {
        
if (o == null)
            
return null;
        
try {
            
return (PersonRef) getORADataFactory().create(o.toDatum(null),
                    OracleTypes.REF);
        }
 catch (Exception exn) {
            
throw new SQLException("Unable to convert "
                    
+ o.getClass().getName() + " to PersonRef: "
                    
+ exn.toString());
        }

    }


    
public Person getValue() throws SQLException {
        
return (Person) Person.getORADataFactory().create(_ref.getSTRUCT(),
                OracleTypes.REF);
    }


    
public void setValue(Person c) throws SQLException {
        _ref.setValue((STRUCT) c.toDatum(_ref.getJavaSqlConnection()));
    }

}

 



//com.baker.object.PersonTableType.java

package com.baker.object;

import java.sql.SQLException;
import java.sql.Connection;
import oracle.jdbc.OracleTypes;
import oracle.sql.ORAData;
import oracle.sql.ORADataFactory;
import oracle.sql.Datum;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;
import oracle.jpub.runtime.MutableArray;

public class PersonTableType implements ORAData, ORADataFactory {
    
public static final String _SQL_NAME = "SOFT1.PERSON_TABLE_TYPE";

    
public static final int _SQL_TYPECODE = OracleTypes.ARRAY;

    MutableArray _array;

    
private static final PersonTableType _PersonTableTypeFactory = new PersonTableType();

    
public static ORADataFactory getORADataFactory() {
        
return _PersonTableTypeFactory;
    }


    
/* constructors */
    
public PersonTableType() {
        
this((Person[]) null);
    }


    
public PersonTableType(Person[] a) {
        _array 
= new MutableArray(2002, a, Person.getORADataFactory());
    }


    
/* ORAData interface */
    
public Datum toDatum(Connection c) throws SQLException {
        
return _array.toDatum(c, _SQL_NAME);
    }


    
/* ORADataFactory interface */
    
public ORAData create(Datum d, int sqlType) throws SQLException {
        
if (d == null)
            
return null;
        PersonTableType a 
= new PersonTableType();
        a._array 
= new MutableArray(2002, (ARRAY) d, Person.getORADataFactory());
        
return a;
    }


    
public int length() throws SQLException {
        
return _array.length();
    }


    
public int getBaseType() throws SQLException {
        
return _array.getBaseType();
    }


    
public String getBaseTypeName() throws SQLException {
        
return _array.getBaseTypeName();
    }


    
public ArrayDescriptor getDescriptor() throws SQLException {
        
return _array.getDescriptor();
    }


    
/* array accessor methods */
    
public Person[] getArray() throws SQLException {
        
return (Person[]) _array.getObjectArray(new Person[_array.length()]);
    }


    
public void setArray(Person[] a) throws SQLException {
        _array.setObjectArray(a);
    }


    
public Person[] getArray(long index, int count) throws SQLException {
        
return (Person[]) _array.getObjectArray(index, new Person[_array
                .sliceLength(index, count)]);
    }


    
public void setArray(Person[] a, long index) throws SQLException {
        _array.setObjectArray(a, index);
    }


    
public Person getElement(long index) throws SQLException {
        
return (Person) _array.getObjectElement(index);
    }


    
public void setElement(Person a, long index) throws SQLException {
        _array.setObjectElement(a, index);
    }


}

 

分享到:
评论
3 楼 nick.s.ni 2012-05-04  
唉,Java中引用的包没有介绍啊,如果数据库用UTF-8的格式,没有问题,如果是其他编码,需要引入oracle其他的包,不然一定会乱码。而且引入之后不需要在自己的类中使用,与Oracle的jdbc实现有关
2 楼 HuanYue 2011-12-31  
我没遇到过相应的问题,你可以看下生成的java类字段对应(类型/顺序)的对不对.建议使用varchar2
1 楼 googixie 2011-12-05  
正好用到,多谢分享!不过我运行后,发现String跟varcharges无法转化,String类型的值到DB就是空的,从DB取出varchar的值到JAVA是乱码,其他的类型,象Integer等确转化正常,请教可能会是什么原因呢?

相关推荐

    Oracle8i_9i数据库基础

    §15.4 在 PL/SQL 中使用 sqlcode,sqlerrm 273 第十六章 存储过程和函数 276 §16.1 引言 276 §16.2 存储过程 276 §16.2.1 创建过程 276 §16.2.2 使用过程 278 §16.2.3 开发存储过程步骤 279 §16.2.3.1 编辑...

    oracle实验报告

    在PL/SQL块中使用SELECT语句时注意几点: (1)SELECT语句必须含有INTO子句。 (2)INTO子句后的变量个数和位置及数据类型必须和SELECT命令后的字段名表相同。 (3)INTO子句后可以是简单类型变量或组合类型变量。 ...

    如何从 Java 存储过程将 JDBC ResultSet 作为 Ref Cursor 返回.doc

    REF CURSOR 是 PL/SQL 中相应的类型。Java 存储过程的调用规范将 ResultSet 映射到 REF CURSOR。在 Oracle9i 之前,不可能从 Java 存储过程直接返回一个 ResultSet,因为没有定义表单 ResultSet-&gt;REF CURSOR 的映射...

    jdbc连接数据库的方式2

    如果利用Oracle的面向对象的技术,可以通过创建一个新的数据库对象类型在数据库中模仿其数据和操作,然后使用JPublisher等工具生成自己的Java bean类。如果使用这种方式,不但Java应用程序可以使用应用软件的对象...

    数据库基础

    §15.4 在 PL/SQL 中使用 sqlcode,sqlerrm 273 第十六章 存储过程和函数 276 §16.1 引言 276 §16.2 存储过程 276 §16.2.1 创建过程 276 §16.2.2 使用过程 278 §16.2.3 开发存储过程步骤 279 §16.2.3.1 编辑...

    java从入门到精通70个PPT

    50 pl/sql 51 Oracle数据库对象 52 提高数据库性能 53 hibernate总结 54 使用Spring容器管理JavaBean 55 Spring 数据访问支持 56-59 项目实战:JBOA办公自动化管理系统 60 Spring配置优化 61 web service 62-65 项目...

    Java/JavaEE 学习笔记

    第三章 PL/SQL数据类型................362 第四章 PL/SQL中的控制语句........368 第五章 PL/SQL游标........................370 第六章 PL/SQL异常........................373 第七章 PL/SQL存储过程..............

    OCPOCA认证考试指南全册:Oracle Database 11g(1Z0-051,1Z0-052,1Z0-053)--详细书签版(第2/2部分)

    7.1.1 对象类型 214 7.1.2 命名模式对象 215 7.1.3 对象名称空间 216 7.2 列举列可用的数据类型 217 7.3 创建简单的表 219 7.3.1 使用列规范创建表 220 7.3.2 使用子查询创建表 221 7.3.3 在创建之后更改表...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    varchar2 1~4000字节 可变长度字符串,与CHAR类型相比,使用VARCHAR2可以节省磁盘空间,但查询效率没有char类型高 数值类型 Number(m,n) m(1~38) n(-84~127) 可以存储正数、负数、零、定点数和精度为38位的浮点数...

    OCPOCA认证考试指南全册:Oracle Database 11g(1Z0-051,1Z0-052,1Z0-053)--详细书签版(第1/2部分)

    7.1.1 对象类型 214 7.1.2 命名模式对象 215 7.1.3 对象名称空间 216 7.2 列举列可用的数据类型 217 7.3 创建简单的表 219 7.3.1 使用列规范创建表 220 7.3.2 使用子查询创建表 221 7.3.3 在创建之后更改表...

    jdbc基础和参考

    从Jdk6.0以后要求,JDBC 4.0 Drivers 必须包括 META-INF/services/java.sql.Driver 文件,有了这个文件以后不需要在显示的使用Class.forName来进行驱动的注册 Oracle数据库进行连接的时候,使用的驱动类: 1....

    OpenEditor:OpenEditor 是一个面向 Oracle 开发人员和 DBA 的文本编辑器-开源

    能够处理大文件(超过 1,000,000 行和大于 100MB),几乎没有行大小限制 (2GB),柱状文本选择和编辑(如在 UltraEdit 中),PL/SQL 匹配搜索(BEGIN/EXCEPTION /END)、文本搜索和替换中的正则表达式、键盘映射自定义...

    J2EE学习笔记(J2ee初学者必备手册)

    第三章 PL/SQL数据类型................362 第四章 PL/SQL中的控制语句........368 第五章 PL/SQL游标........................370 第六章 PL/SQL异常........................373 第七章 PL/SQL存储过程..............

    asp.net知识库

    在ASP.NET中使用WINDOWS验证方式连接SQL SERVER数据库 改进ADO.Net数据库访问方式 ASP.NET 2.0 绑定高级技巧 简单实用的DataSet更新数据库的类+总结 [ADO.NET]由数据库触发器引发的问题 为ASP.NET封装的SQL数据库...

    Java学习笔记-个人整理的

    {13.8}java.util.Date与java.sql.Date比较}{200}{section.13.8} {13.9}Meta Data}{201}{section.13.9} {13.10}可滚动结果集}{201}{section.13.10} {13.11}Procedure}{201}{section.13.11} {14}xml}{204}{...

    一个好用的数据库类

    例如我们可以把很多信息按照一定的格式保存在文本中(因为在商业上用别人的数据库都是要买的),然后通过ODBC把这些文本文件映射成表,这些文件的目录就成为一个数据库,这些我们就可以很方便的对这些文件的内容通过...

    VC与Labview、Matlab编程论文资料

    VC与STK的集成及在****数字可视化仿真中的应用.pdf VC中应用MSComm控件实现串口通信.pdf VC平台下基于OLE的Word自动化操作应用.pdf VC平台中的ProE二次开发研究.pdf VC环境下纸箱打样机的矢量图形系统软件开发....

    VC与Labview、Matlab编程论文资料[2].rar

    VC与STK的集成及在****数字可视化仿真中的应用.pdf VC中应用MSComm控件实现串口通信.pdf VC平台下基于OLE的Word自动化操作应用.pdf VC平台中的ProE二次开发研究.pdf VC环境下纸箱打样机的矢量图形系统软件开发....

    VC与Labview、Matlab编程论文资料[4].rar

    VC与STK的集成及在****数字可视化仿真中的应用.pdf VC中应用MSComm控件实现串口通信.pdf VC平台下基于OLE的Word自动化操作应用.pdf VC平台中的ProE二次开发研究.pdf VC环境下纸箱打样机的矢量图形系统软件开发....

Global site tag (gtag.js) - Google Analytics