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

本文介绍Oracle JPublisher工具,演示如何创建PL/SQL类型并生成对应的Java对象,还展示了使用这些对象调用存储过程的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、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);
    }


}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值