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: oracle ora92
SET  JDBC_LIB = %ORACLE_HOME% jdbc lib
SET  SQLJ_EXE_HOME = %ORACLE_HOME% bin
SET  SQLJ_LIB = %ORACLE_HOME% sqlj lib
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);
    }


}


本文转自:http://blog.csdn.net/fk_baker/article/details/2452579

你可能感兴趣的:(Oracle 中Java 对象与PL/SQL类型的映射及使用)