一、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 = ...{ 12, 12, 2, 91 };
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);
}
}