`

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等确转化正常,请教可能会是什么原因呢?

相关推荐

    PL/SQL Developer 插件

    PL/SQL Developer是一款专为Oracle数据库开发人员设计的集成开发环境(IDE),它提供了一整套工具来编写、调试、测试和优化PL/SQL代码。这个"shortcuts"插件是为了提升开发效率,通过快捷键的方式帮助用户快速输入...

    pl/sql语法详解

    PL/SQL,全称为Procedural Language/Structured Query Language,是Oracle数据库的一种扩展,它将SQL语句与过程式编程语言结合在一起,为数据库管理提供了更强大的功能。本教程将全面解析PL/SQL的语法和应用,是学习...

    Oracle_PLSQL.rar_Java plsql_oracle_oracle doc_pl sql_plsql

    - **数据类型**:包括数值型(NUMBER、BINARY_INTEGER、INTEGER等)、字符型(VARCHAR2、CHAR、LONG等)、日期型(DATE)和PL/SQL对象类型。 2. **PL/SQL与SQL的结合** - **嵌入式SQL**:PL/SQL可以直接嵌入SQL...

    PL/SQL客户端配置文件

    PL/SQL客户端配置文件是用于建立PL/SQL Developer或类似工具与Oracle数据库服务器连接的关键设置。这些配置文件确保用户能够顺利地通过客户端工具访问服务端的Oracle数据库实例。在描述中提到的“PL/SQL客户端连接...

    Oracle PL-SQL语言初级教程

    PL/SQL的优点包括高效的数据处理能力,对所有SQL数据类型、SQL函数以及Oracle对象类型的支持,可重用性,以及良好的安全性。由于PL/SQL被整合在Oracle服务器和工具中,因此它可以方便地与其他Oracle产品交互,增强了...

    精通Oracle 10g Pl SQL編程

    6. **PL/SQL与Oracle对象类型** - 定义和使用用户自定义类型(UDT),如对象类型、集合类型等。 - 对象关系映射(ORM):通过PL/SQL操作复杂数据结构,例如对象表和嵌套表。 7. **PL/SQL性能优化** - 查询优化:...

    java c/s sql srever oracle转换

    在转换过程中,需要确保所有表结构、字段数据类型与Oracle兼容,并更新Java代码中的SQL语句。 3. **JDBC驱动更换**:Java通过JDBC(Java Database Connectivity)接口与数据库交互。转换过程中,需要从SQL Server的...

    Oracle与.Net 数据类型映射

    了解Oracle数据库与.NET数据类型的映射关系对于开发人员来说至关重要,这直接影响到数据的正确存储、检索和处理。以下是对"Oracle与.Net 数据类型映射"这一主题的详细解释。 首先,Oracle数据库提供了一系列的数据...

    JPublisher生成Oracle对象类型对应的Java对象例子

    JPublisher是Oracle JDBC驱动程序的一部分,它允许我们将Oracle的对象类型映射到Java类,这样我们就可以在Java应用程序中方便地操作这些对象。 标题“JPublisher生成Oracle对象类型对应的Java对象例子”指的是使用...

    sqlserver自动生成sql语句工具sqlserver转oracle

    1. 数据类型映射:SQL Server和Oracle的数据类型可能存在差异,如SQL Server的`datetime`对应Oracle的`timestamp`,`varchar2`对应`nvarchar2`等,工具会自动进行转换,但也可能需要手动调整。 2. 函数和过程转换:...

    oracle调用java程序

    - **PL/SQL接口**:通过PL/SQL存储对象,如过程和函数,实现Java与SQL和PL/SQL的通信。 2. **Oracle JDBC的连接类型** - **瘦驱动(Thin Driver)**:客户端直接与数据库服务器通信,无须中间层,适合分布式应用...

    PL/SQL教程6 总共6个ppt

    - 触发器是一种数据库对象,它与数据库中的表、视图等关联,当这些对象上发生特定的DML(Insert, Update, Delete)或DDL(Create, Alter, Drop)操作时,触发器会自动执行预先定义的PL/SQL代码。 - 触发器的主要...

    PL/SQL Developer 9.0 用户指南

    - **置换变量**:在SQL语句中使用变量代替固定的值。 - **更新数据库**:提供直观的界面来进行表数据的插入、更新和删除操作。 - **查看和编辑XMLTYPE列**:支持直接编辑存储在XMLTYPE列中的数据。 - **直接查询导出...

    Oracle使用PL/SQL操作COM对象

    3. **数据类型映射**:理解PL/SQL数据类型与COM对象类型之间的对应关系至关重要,这样才能正确地传递参数和处理结果。 #### 四、实践示例 以操作Excel对象为例,我们可以创建一个PL/SQL函数来读取或写入Excel文件。...

    Oracle+PlSql存储过程

    Oracle PL/SQL存储过程是Oracle数据库中的一种重要编程机制,用于封装复杂的数据库操作逻辑,提高数据库性能,并且便于代码管理和重用。以下是对Oracle存储过程的详细解释。 **Oracle存储过程基础知识** Oracle存储...

    Java连接Oracle数据库的各种方法

    在Oracle中,JDBC驱动程序是内置于数据库的虚拟机中,这使得Java程序可以直接调用数据库中的SQL和PL/SQL。Oracle8i提供了三种类型的JDBC驱动:JDBC OCI、JDBC Thin和JDBC KPRB。JDBC OCI类似于传统的ODBC驱动,需要...

    《精通Oracle 10g Pro*C/C++编程》源代码与学习笔记

    2. **数据类型映射**:在C/C++中使用Oracle的数据类型,如NUMBER、DATE、VARCHAR2等,需要理解它们如何映射到C/C++的原始数据类型,并在Pro*C中正确声明。 3. **游标和绑定变量**:游标是Oracle中的一个关键概念,...

    java代码中的sql语句处理.rar_JAVA SQL处理

    然而,直接将PL/SQL(Oracle数据库特有的SQL扩展)中的语句转换为Java可使用的形式可能涉及以下内容: - **CallableStatement**:对于存储过程或函数,可以使用`CallableStatement`,它允许调用数据库的存储过程并...

    Oracle.PL.SQL程序设计_第五版_上下册.Steven.Feuerstein&Bill;.Pribyl.RAR

    15. **面向对象编程**:Oracle支持的对象类型、对象关系映射以及面向对象编程的概念。 通过这两册书的学习,读者不仅可以掌握Oracle PL/SQL的基本语法和高级特性,还能了解如何设计和实现复杂的数据库解决方案。...

Global site tag (gtag.js) - Google Analytics