




已阅读5页,还剩35页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Oracle中的Java体系结构 目前,使用Java来扩展存储程序是一种很流行的方法。在使用Java类库处理数据的过程中,PL/SQL是必不可少的一环,这是因为PL/SQL 封装了Java类库的数据访问,即任何Java存储对象访问的数据都必须经过PL/SQL。由于本章的所有内容只被最新的数据库版本所支持,因此它独立于本书的其他章节,以下是本章要介绍的内容: Oracle中的Java体系结构 Oracle JDBC的连接类型 客户端驱动器(Client-side driver),即JDBC瘦驱动(thin driver) Oracle调用接口驱动器,即中间层胖驱动(middle-tier thick driver) Oracle 服务器端内部驱动器(Oracle Server-Side Internal Driver),即服务器级的胖驱动 在Oracle中创建Java类库 创建内部服务器的Java函数 创建内部服务器的Java过程 创建内部服务器的Java对象 创建、装载、删除、使用Java类库时的故障诊断 映射Oracle类型本章将向您展示一张Oracle中巨大的Java组织结构图,在解释了Java的体系结构之后,您还会看到开发和扩展Java组件的方法。使用Java扩展的原因:我们将使用PL/SQL作为存储Java类库和其他PL/SQL存储程序或匿名块程序之间的接口。我们还会映射Oracle和Java之间的本地数据类型和用户自定义数据类型,以便能定义有效接口和支持JSP (Java Server Page,Java服务器页面)。1 Oracle中的Java体系结构Oracle 9i和10g版本的数据库为开发服务器端或内部Java程序组件提供了一个健壮的体系结构。Java组件采用OO (Object-Oriented,面向对象)的结构,这样的结构非常适合Oracle的对象-关系模型(Object-Relational model)。组件的体系结构实际上就是一个库栈,它包含: 操作系统的平台依赖性,例如UNIX、 LINUX、 Microsoft Windows; 依赖Oracle数据库的文件和库管理; 独立于平台的JVM (Java Virtual Machine,Oracle Java虚拟机); Java内核类库,兼容不同的平台; Oracle支持的Java API (Application Programming Interfaces,应用程序接口),如SQLJ、JDBC和JNDI; Oracle的PL/SQL存储对象,为SQL和PL/SQL程序之间提供接口,就像服务器端Java类库一样。Oracle和Java库就和普通的文件系统一样来存储和管理应用程序,它们屏蔽了不同操作系统的结构差异和系统限制,从而建立起一个独立于平台的存储、检索和恢复文件的统一处理过程。同时,Java虚拟机为创建有大量文档支持的OO程序提供了一个标准环境。另外,Oracle PL/SQL也为其他PL/SQL存储对象以及SQL访问Java库提供了软件包。下图5-1给出了Oracle JVM(Java虚拟机)的体系结构。Oracle JVM使用两种格式的命名空间:长名称和短名称。长名称和Java中类的命名模式是一样的,我们可以用它本来的命名空间来调用存储Java程序。然而,本章中Java示例的名称都是短名称,并且程序也没有放进程序包中。当然,您完全可以将您的Java程序放进程序包中。Java存储代码的命名空间包括了程序包的整个层次。如果命名空间的长度超过30个字符,Oracle在数据字典视图中就使用哈希命名空间。使用DBMS_JAVA包和LONGNAME函数可以获得完整的命名空间,而如果要获取短名称可以使用DBMS_JAVA程序包和SHORTNAME函数。图5-1 Oracle JVM体系结构JVM具有自动内存管理的功能,这意味着我们不需要手动分配和释放内存空间。同时,就像PL/SQL一样,Java也是强类型的语言。因此,强类型和垃圾回收器相结合,对内存进行管理,为Java提供了一个简单的、富有弹性的环境,就像PL/SQL的运行时引擎一样。Java和PL/SQL都是解释语言,因此它们要求JIT(Just-In-Time,即时)编译。Oracle 9i中可以对PL/SQL和Java程序进行本地编译,而这实际上是提前编译了。本地编译将PL/SQL和Java程序的字节代码转换成机器可执行的程序代码。因为本地编译消除了即时编译的延时,所以提高了执行速度。但不幸的是,它却要花些时间将解释过的程序编译为机器代码。权衡之下,如果您并不经常改变代码,本地编译是一个好的选择。如下所示,有3种方法可将Oracle的Java文件嵌入到数据库实例中:(1) 处理过程分两步:(a)使用javac编译Java源文件,产生Java字节码程序。(b)使用Oracle loadjava工具将文件放入数据库实例。(2) 一步处理即可,使用loadjava工具编译文件,并将编译后的Java类文件放入数据库实例。(3) 一步处理过程,像处理存储Java类一样使用DDL (Data Definition Language,数据定义语言)创建和编译Java源文件。Oracle 9i R1中的语法分析程序有时会出现问题,并且在Oracle 9i R1中使用DDL命令创建Java程序可能会失败。在9i R2以及以后的版本中这些问题都得到了解决。本章所有的示例都将编译并通过使用loadjava工具载入数据库实例中。小提示:如果选择使用上面的第二种方法,那么在我们试图重写文件时,可能会产生ORA-29533错误,这是因为在一些数据库版本中并不支持loadjava工具的替换(replace)选项。要解决这个问题,您只需要使用dropjava工具并附带user选项删除.class文件,然后重新运行loadjava工具载入文件即可。本章假设您对Java有一个基本的了解,即能够编译和运行Java程序。本章所有的示例都提供了实例命令行说明。在附录D中有关于这方面的内容的一个基本指南,并且提供了Java环境配置说明。Java的存储程序体和传统的PL/SQL程序体很像,由单个会话使用定义者权限或调用者权限访问模式调用它们。但Java在Oracle数据库实例的内部和外部的工作方式有一些不同之处,这些不同之处如下所示: 首先是执行的控制有明显的不同,Oracle实例外部的Java应用程序包含main()方法,并通过调用它来运行程序,而在实例内部的Java程序则没有包含main()方法。在Oracle实例中存储的Java程序有两种类型的行为,它们是: 第1种Java程序的功能相当于具有函数和过程的包,它是一些不可实例化的类。这就要求程序中的所有变量和方法必须是静态的,即将它们作为类的方法。作为具有函数和过程的PL/SQL 包的镜像,这限制了它们的范围。为了更易于访问外部Java程序,这种程序代码的语法有所改变。 第2种Java程序的功能相当于对象类型体的实现,它们是一些可以实例化的类,并且程序中的变量和方法可以是静态的,也可以是非静态的。但与外部Java类不同的是,它们的构造函数不能被重载,即它们只有一个默认的构造函数。JDBC2 API中的SQLData接口用于实例化这种类型的程序,并且实例化还包含了在PL/SQL和Java间映射数据类型。 Java类以Java字节码的形式保存在一个空文本中,并压缩为Oracle数据库实例的外部Java档案文件。Oracle把它们作为源、类以及Java对象资源来管理。模式中包含一个JAVA$OPTIONS表,它可被DBMS_JAVA包、SET_COMPILER_OPTION和RESET_COMPILER_OPTION过程或GET_COMPILER_OPTION函数访问和配置。 内部Java类文件并不支持用户接口,这意味着它们不能被直接输出到控制台或本地声音设备。声音文件可以在Oracle内部处理,但它们不能访问本地声音设备。与Oracle 9i相比,Oracle 10g稍微有些改变,因为它使用的是Java SDK 1.4.x,支持Headless(无头) AWT。 Oracle内部的Java类的名称有两种格式。一种是支持标准模式数据库对象的短格式,它最长可以有30个字符。当一个类的名称超过长度限制时,Oracle将自动创建一个哈希名称作为类的短名称,并将长名称存放在别处。 Oracle内部Java类不支持标准Java的Class.forName()方法。但Oracle 9i和Oracle10g支持使用多个分解器来定位类。若使用其中一个来定位类,结果却是运行另一个分解器,我们就会得到意料之外的结果。 操作资源是受严格限制的,您必须拥有SYSDBA用户权限才能变更它们。可以使用DBMS_JAVA包和GRANT_PERMISSION过程像IO文件来一样打开操作资源。 Java线程针对Oracle内部的Java类工作方式与外部类有所不同。Oracle JVM使用的是非抢占的线程模式。这意味着所有的线程运行在一个单一的操作系统线程中,Oracle JVM仅是在线程之间切换上下文。切换上下文的意思是,Oracle JVM以循环的方式在每一个时间段产生一个线程,直至所有线程结束。注意:正在使用Oracle版本会告诉您应该使用哪个版本的JDK(Java Software Development Kit,Java软件开发包)。为简单起见,本章所有的示例都是使用Oracle 9i支持的Java SDK 1.3开发的。同时,它们也被Java SDK 1.4所支持。Oracle Java开发人员向导列出了两个关键的错误代码,但其实还存在很多其他的错误代码。在这我们并不想列出这些错误代码,而是将它们放在在本章后面的“创建、装载、删除、使用Java类库时的故障诊断”一节介绍。现在我们已经回顾了Oracle Java体系结构的一些关键组件,下一节将介绍几种JDBC驱动程序。上一页首页下一页 2 Oracle JDBC连接类型为了满足不同的应用需求,Oracle有3种方法实现JDBC (Java Database Connection,Java 数据库连接)。它们是瘦(thin)连接、胖连接和默认连接,分别对应于客户端驱动、服务器端驱动、调用接口驱动(或中间层驱动)。下一节会分析这3种连接方式。2.1 客户端驱动或JDBC瘦驱动Oracle瘦连接大概是Java应用程序、JSP、EJB (Enterprise Java Beans,企业级Java Bean)等最常用的一种连接方式了,它为不直接访问Oracle库文件而创建代码提供了许多便利。因为建立和配置Oracle JDBC瘦驱动器的要求最低,所以外部Java应用程序能够使用多个这样的连接,但首先得保证Java编程环境已经包含了标准的Java库和Oracle JDBC库。这可以通过配置CLASSPATH环境变量来实现。另外要注意的一点就是,环境变量中必须设置有Oracle classes12.zip这个Java档案文件的路径。书后的附录D对此作了详细介绍。不幸的是,如果没有配置并启动数据库监听程序,我们就无法使用Oracle JDBC瘦驱动器。在每一次连接一个数据库实例时,我们都需要都要输入主机名、监听程序使用的端口号、数据库名和用户名以及口令。使用客户端驱动的原因:当Java程序连接Oracle数据库时,我们应该知道连接的配置选项。如果我们了解不同的连接方式的工作原理,那么在应用程序连接Oracle实例时,我们可以更好地选择正确的JDBC驱动程序。对于Oracle程序集来说,Java是非常有用的扩展。但不幸的是,在选择使用一项Java技术去解决问题之前,我们得理解Java选项之间的细微差别,这对解决问题是非常关键的。我们相信,如果理解了Java选项,那么就能够在我们的应用程序中更好地使用Java技术。小提示:如果输入的主机名、监听程序端口号或数据库名不正确,那么Oracle客户端或瘦驱动会返回一个无意义的错误消息。实际上,它会报告17002错误。在JDBC API的Oracle实现中会找到这个错误。附录D中演示了一个检查这个错误的清理机制。外部Java应用程序、JSP、EJB在使用Oracle JDBC 瘦驱动时会受到限制。一个多线程的Java servlet就是这样一个执行Oracle JDBC瘦驱动文件而受到限制的Java应用程序示例。Oracle JDBC瘦连接可以是开放式的连接,也可以是保守式的连接。开放式的连接是临时性的连接,它使用HTTP协议进行传输,即时限为15秒的管道TCP套接字连接。这种连接方式非常适合与JSP,但要使用大量资源,因为它必须为每一次通信建立连接。保守连接在连接过程中始终开启状态提醒(state-aware)TCP套接字。Java servlet通过使用保守连接来创建和维持数据库连接池。另外,通过使用两层(two-tier)或多层次(n-tier)解决方案实现Java servlet,从而避免了使用通过HTTP协议实现的使用大量资源的、短暂的连接方式。2.2 Oracle调用接口驱动或中间层胖驱动和Oracle JDBC瘦驱动器相比,Oracle调用接口(OCI)驱动与Oracle C/C+库耦合得更加紧密。如果要使用Oracle调用接口,我们需要保证PATH、CLASSPATH和LD_LIBRARY_PATH环境变量映射到了Oracle库。这些库都需要基于相同的物理平台或通过存储区域网络(SAN)映射,如UNIX中的NFS。Java servlet使用OCI驱动可以保持持久连接池。但OCI驱动器的性能不如Oracle JDBC瘦驱动。一般来说,如果在servlet中使用Oracle JDBC瘦驱动,配置连接会容易一些。但如果要保持Java servlet的活跃连接池,瘦驱动的性能会变得很差。2.3 Oracle 服务器端内部驱动或服务器层胖驱动Oracle 服务器端内部驱动同样紧密耦合并依赖于Oracle C/C+ 库。但不幸的是,只有这一种方法可以将Java程序作为Oracle数据库中的存储对象来创建。Oracle 服务器端内部驱动使用连接类中的defaultConnection()方法连接数据库。如果我们希望在外部测试Java程序,那么在测试时会出现一点问题。我们最好在的开发实例中测试Java代码而不是去创建一个工作区。与OCI驱动器不同,Oracle 服务器端内部驱动比Oracle JDBC瘦驱动器快。如果您阅读本章并研究了实例代码,您会发现,将Java嵌入Oracle数据库需要一些技巧和技术。下一节将研究如何创建和检查类库和实例化的Java存储对象。3 在Oracle中创建Java类库有两种类型的Java类库可供创建,即调用者接口驱动(中间层)Java类库或服务器端Java类库。在Apache服务器中,调用接口Java库的行为很像服务器端Java库,它们必须复制到Apache服务器的每个位点上,并使用web服务器负载平衡工具管理。这些组件的行为很像调用Oracle服务器的外部程序,关于这方面的内容在一些介绍企业级Java的书中有更详细的讨论。在Oracle中创建Java类库的原因:我们应该知道一个Java类是属于数据库内部Java库还是属于外部Java库。部署在数据库内部的库定义都很明确,但使用的范围却很窄。同样的,外部库组件的功能强大,但使用起来却不如本地存储对象方便。您需要了解这两项技术的特点,以便针对实际应用情况选择好的部署方式。注意:如果程序中没有直接包括调用接口驱动,即中间层Java类库,那么引用它们需要指出它们在Oracle OCI库中的路径。但在这里要注意的是,除了Oracle应用程序服务器,别的web服务器上都没有部署OCI库。作为Oracle数据库的子部件,服务器端Java类库保存在Oracle JVM中。服务器端Java类库是本章的核心内容。接下来的两节将向您介绍创建内部服务器Java函数和过程的方法。注意:如果您对Java JDBC连接的配置和测试感到陌生,请参考附录D的说明。Java程序可以很简单,也可以很复杂,本章中的Java程序示例都是简单易懂的,运行这些示例要使用两个关键可执行程序,它们是: javac 将Java程序的文本文件编译成Java可执行文件。 java 运行Java可执行文件。Java文件的命名习惯是区分大小写的,因此您应该确保文件的名字和网页代码文件名相同。如果您试图编译一个文件名和类名不相同的Java文件,那么会返回一个错误。另外,Java程序文件的扩展名是小写的.java。现在我们可以创建一个简单的HelloWorld1.java文件来看一看Java程序的工作原理。如果您使用的是Microsoft Windows系统,打开一个命令行窗口。如果您使用的是UNIX系统,打开一个终端窗口,下面是HelloWorld.java的代码:- Available online as part of HelloWorld1.java file./ Class definition.public class HelloWorld1/ -/ Static main to print Hello World.public static void main(String args)/ Print the message to console.System.out.println(Hello World.); / End of static main./ -/ / End of HelloWorld1 class.使用下面的命令编译Java文本文件:javac HelloWorld1.java如果程序编译成功将不会给控制台返回任何消息,这表示程序语法完全正确。但若要验证Java的可执行文件运行是否正确,则首先使用Microsoft Windows的目录(dir)命令或UNIX的列表(ls)命令找到HelloWorld1.*文件所在的工作目录。在控制台上您会看到下面两个文件:HelloWorld1.javaHelloWorld1.class创建了可执行文件后,使用下面的命令测试文件的执行情况:java HelloWorld1注意:运行Java程序时,不必在要运行的程序名后面加.class扩展名,因为这是默认的。如果在文件名后面加上.class会引发下面异常:java.lang.NoClassDefFoundError:HelloWorld1/class.小提示:如果PATH和CLASSPATH环境变量中没有设置当前工作目录,执行程序时同样会引发java.lang.NoClassDefFoundError: HelloWorld1/class错误。返回结果如下:Hello World.下一节将介绍创建服务器端即内部服务器Java程序体。我们将学习如何通过创建Java类文件,来支持存储函数和过程以及如何封装PL/SQL包中已有的函数和过程这两方面的内容。接下来两节的内容是连续的,第二节的内容建立在第一节的基础之上。3.1 创建内部服务器Java函数通过编写使用在服务器端内部或JDBC胖连接上的Java类文件,可以创建内部服务器Java函数。就像本章前面所介绍的那样,JDBC胖连接依赖于OCI库。Java类文件在载入Oracle JVM后就可以直接访问所有的OCI库了。创建Java内部即服务器端类文件分3步:首先,创建并编译类文件;接下来使用Oracle loadjava工具将编译过的类文件载入服务器;最后,创建一个Java类文件的PL/SQL包装。下面假设Java的CLASSPATH 和PATH环境变量是正确的。如果您仍然不能编译或测试Java程序,那么可能是您的环境配置不正确。正如前面所提及的那样,查阅附录D,确保您的环境配置得正确。使用内部服务器Java函数的原因:我们使用内部服务器Java函数和编写PL/SQL函数的目的是一样的,都是为了处理并返回一个不包含DML(Data Manipulation Language,数据操作语言)命令的结果,不仅如此,内部Java函数还能够镜像PL/SQL函数和调用外部库来使用JAR (Java Archive Repository,Java档案存储)文件。当我们使用Java编写应用程序并且希望开发团队使用相同的语言编写服务器端代码时,上面这个特性非常有效。同时这个特性还能使开发团队在编写Java代码时,最大程度上减少错误出现的可能性。下面这个示例创建了具有两个方法的一个Java类库。类库中的两个方法都重载了,即改变了它们的签名或者说是形参列表。它们返回一个可变长度数组或Java字符串。两个重载的方法将会对应于两个重载PL/SQL函数,它们返回值的类型为本地Oracle数据类型VARCHAR2。HelloWorld2.java的代码如下所示:- Available online as part of HelloWorld2.java file./ Oracle class imports.import oracle.jdbc.driver.*;/ Class definition.public class HelloWorld2/ -/ The Hello method.public static String hello()/ Call overloaded method with a null String.return Hello World.; / End of hello() method./ -/ The hello method.public static String hello(String name)/ Call overloaded method with a null String.return Hello + name + .; / End of hello() method./ -/ Static main to test instance outside of Oracle.public static void main(String args)/ Print the return message to console.System.out.println(HelloWorld2.hello();/ Print the return message to console.System.out.println(HelloWorld2.hello(Larry); / End of static main./ -/ / End of HelloWorld2 class.脚本执行以下任务: 定义了一个具有两个Hello() 方法的类,但方法经过了重载,即它们具有不同的签名或者说是形参列表。这两个方法都是静态的方法,因为PL/SQL封装包只能调用静态的方法。静态方法并不要求有一个类的实例来运行它,它们的功能很像一个C函数或PL/SQL存储包中的函数。 定义一个方法main(),在将程序载入Oracle数据库实例前,您可以使用这个方法来测试程序。当类文件载入Oracle实例时会忽略main()方法。main()方法调用静态Hello()和Hello(String name)方法,并将实参输出到控制台。一般来说,在将程序载入数据库之前,可以先删除诸如main()方法这样的测试组件。不过如果它们留了下来,也不会影响存储Java类库。使用下面的命令测试Java程序:java HelloWorld2控制台上的输出如下所示:Hello World.Hello Larry.如果您不建立PLSQL模式,那么现在请运行create_user.sql脚本。当您建立了PLSQL模式后,就像本章前面介绍的那样,使用javac工具编译程序。接下来,使用loadjava工具将程序载入Oracle JVM中,如下所示:loadjava -r -f -o -user plsql/plsql HelloWorld2.class注意:在Microsoft操作系统中,您可能会得到如下错误提示:The procedure entry point kpuhhalo could not be located in the dynamic link library OCI.dll. (过程的入口点kpuhhalo不能定位到动态连接库 OCI.dll),这是因为在您的PATH环境变量中没有设置%ORACLE_HOMEbin%路径。在PLSQL模式下,loadjava工具命令将Java类文件HelloWorld2载入Oracle JVM中。在将Java类文件载入数据库之后,您需要创建一个PL/SQL封装包来使用它。下面的HelloWorld2.sql脚本创建了包和包主体,并将其作为Java类库的封装包。- Available online as part of HelloWorld2.sql file.- Create a PL/SQL wrapper package to a Java class file.CREATE OR REPLACE PACKAGE hello_world2 AS- Define a null argument function.FUNCTION helloRETURN VARCHAR2;- Define a one argument function.FUNCTION hello( who VARCHAR2 )RETURN VARCHAR2;END hello_world2;/- Create a PL/SQL wrapper package to a Java class file.CREATE OR REPLACE PACKAGE BODY hello_world2 AS- Define a null argument function.FUNCTION helloRETURN VARCHAR2 ISLANGUAGE JAVANAME HelloWorld2.Hello() return String;- Define a null argument function.FUNCTION hello( who VARCHAR2 )RETURN VARCHAR2 ISLANGUAGE JAVANAME HelloWorld2.Hello(java.lang.String) return String;END hello_world2;/脚本执行以下任务: 创建了两个返回值的类型为VARCHAR2的重载函数Hello,其中一个函数没有参数,另一个函数有一个形参; 创建了具有两个重载函数Hello的包主体用于实现一个存储Java类文件。PL/SQL NAME关键字提供对存储Java类文件和返回值的一个引用。您必须给出形参所属类型的完全路径,就像java.lang.String引用这样。返回类型可以是短的String,因为Oracle将其理解为外部数据类型。您可以通过查询user_objects视图验证目前用于测试的所有组件,如下所示:- Available online as part of HelloWorld2.sql file.SELECT object_name, object_type, statusFROM user_objectsWHERE object_name IN (HelloWorld2,HELLO_WORLD2);脚本返回如下结果:- This output is generated from the online HelloWorld2.sql file.OBJECT_NAME OBJECT_TYPE STATUS- - -HELLO_WORLD2 PACKAGE VALIDHELLO_WORLD2 PACKAGE BODY VALIDHelloWorld2 JAVA CLASS VALID如果您得到的结果和上面的不一样,那么在继续前进之前,请查一查是否忽略了哪一步。如果得到的结果相同,那么现在就可以在SQL和PL/SQL中测试Java类库了。您可以在SQL中使用一个查询或在PL/SQL中使用DBMS_OUTPUT.PUT_LINE语句来测试类库。下面是封装包的一个SQL查询,它使用了内部Java类文件:SELECT hello_world2.hello(Paul McCartney)FROM dual;查询返回下面的结果:HELLO_WORLD2.HELLO(PAULMCCARTNEY)-Hello Paul McCartney.现在您了解了如何创建Oracle数据库存储Java类文件实例将方法映射为函数。下一节将研究如何创建组件来实现过程的功能。3.2 创建内部服务器Java过程创建过程的规则和创建函数的规则很相似。PL/SQL过程有IN或者IN 和 OUT两种模式。然而,当封装一个Java方法时,在PL/SQL中不能使用IN 和 OUT这种模式。如果您试图定义包主体中含有一个具有IN和OUT模式的过程,那么会引发下面的异常:PLS-00235: the external type is not appropriate for the parameter现在我们可以创建一个具有IN模式的过程作为一个Java类方法的封装,当您在过程的上下文中使用Java方法时,Java方法将会返回void类型。使用内部服务器Java过程的原因:与编写PL/SQL过程的目的一样,我们使用内部服务器Java过程,是为了处理包含DML命令的结果集,结果集可能返回也可能不返回结果。同样的,内部Java过程也能够镜像PL/SQL函数和调用外部库来使用JAR文件。当我们使用Java编写应用程序,并且希望开发团队使用相同的语言编写服务器端代码时,上面这个特性非常有效。同时,这个特性还能使开发团队在编写Java代码时,最大程度上减少错误出现的可能性。下面的Java源文件支持一个具有IN模式的PL/SQL过程:- Available online as part of HelloWorld3.java file./ Oracle class imports.import java.sql.*;import oracle.jdbc.driver.*;/ Class definition.public class HelloWorld3/ Define the doDML() method.public static void doDML(String statement,String name) throws SQLException/ Define a connection for Oracle.Connection conn = new OracleDriver().defaultConnection();/ Define and initialize a prepared statement.PreparedStatement ps = conn.prepareStatement(statement);/ Assign the cursor return.ps.setString(1,name);ps.execute(); / End of the doDML() method./ -/ Define the doDQL() method.public static String doDQL(String statement) throws SQLException/ Define and initialize a local return variable.String result = new String();/ Define a connection for Oracle.Connection conn = new OracleDriver().defaultConnection();/ Define and initialize a prepared statement.PreparedStatement ps = conn.prepareStatement(statement);/ Execute a query.ResultSet rs = ps.executeQuery();/ Use a while-loop even though only one row is returned.while (rs.next()/ Assign the cursor return.result = rs.getString(1);/ Return the user name.return result; / End of the doDQL() method. / End of HelloWorld3 class.脚本完成以下任务: 定义了一个具有两个静态方法的类,其中一个方法返回void,另一个返回一个映射为VARCHAR2类型的String,这两个方法完成以下功能: myDML()方法有两个String类型的形参,第一个接收SQL语句,第二个传送要插入的数据。myDML()方法使用第一个形参创建Connection和PreparedStatement,然后将第二个参数映射到SQL语句并执行语句,这就是DML语句的模式; myDQL()方法有一个带符号的形参,用于接收SQL查询语句作为实参。myDQL()方法使用这个形参创建Connection和PreparedStatement,并将while-loop循环选取的最后一行记录作为一个String返回。HelloWorld3.java类文件中没有包含main()方法。若要在数据库外部使用main()方法测试程序,需要将连接转换到客户端驱动或OCI驱动方式。如果您希望在数据库实例外部进行测试,请参阅附录D。大部分情况下,您已经建立了PLSQL模式,但如果没有建立,那么现在请运行create_user.sql脚本。当您建立了PLSQL模式后,就像本章前面介绍的那样,使用javac工具编译程序,然后,使用loadjava工具将程序载入Oracle JVM中,如下所示:loadjava -r -f -o -user plsql/plsql HelloWorld2.class在PLSQL模式下,loadjava命令将Java类文件HelloWorld3载入Oracle JVM中。在Java类文件载入数据库以后,您应该创建表mytable和PL/SQL封装包来使用它。使用下面的命令创建mytable表:- Available online as part of HelloWorld3.sql file.CREATE TABLE mytable (character VARCHAR2(100);下面的HelloWorld3.sql脚本创建了包和包主体,并将其作为Java类库的封装包:- Available online as part of HelloWorld3.sql file.- Create a PL/SQL wrapper package to a Java class file.CREATE OR REPLACE PACKAGE hello_world3 AS- Define a single argument procedure.PROCEDURE doDML( dml VARCHAR2, input VARCHAR2 );- Define a single argument function.FUNCTION doDQL( dql VARCHAR2 )RETURN VARCHAR2;END hello_world3;/- Create a PL/SQL wrapper package to a Java class file.CREATE OR REPLACE PACKAGE BODY hello_world3 AS- Define a single argument procedure.PROCEDURE doDML( dml VARCHAR2, input VARCHAR2 ) ISLANGUAGE JAVANAME HelloWorld3.doDML(java.lang.String,java.lang.String);- Define a single argument function.FUNCTION doDQL( dql VARCHAR2 )RETURN VARCHAR2 ISLANGUAGE JAVANAME HelloWorld3.doDQL(java.lang.String) return String;END hello_world3;/脚本执行以下任务: 创建了拥有一个过程和一个函数的包,包完成以下任务: 包中的doDML过程具有两个VARCHAR2类型形参。 包中的doDQL函数具有一个VARCHAR2类型形参,并返回一个VARCHAR2类型的值。 通过将存储Java类文件映射给包,将类中的方法映射给过程和函数, 脚本创建了具有上面的过程和函数的包主体。PL/SQL NAME关键字提供对存储Java类文件和返回值的一个引用。我们必须给出形参所属类型的完全路径,就像java.lang.String引用这样。我们可以通过查询user_objects视图验证目前用于测试的所有组件,如下所示:- Available online as part of HelloWorld3.sql file.SELECT object_name, object_type, statusFROM user_objectsWHERE object_name IN (HelloWorld3,HELLO_WORLD3);脚本返回如下结果:- This output is generated from the online HelloWorld3.sql file.OBJECT_NAME OBJECT_TYPE STATUS- - -HELLO_WORLD3 PACKAGE VALIDHELLO_WORLD3 PACKAGE BODY VALIDHelloWorld3 JAVA CLASS VALID如果您得到的结果和上面的不一样,那么在继续前进之前,请查一查您是否忽略了哪一步。如果得到的结果相同,那么现在就可以在SQL和PL/SQL中测试Java类库了。您可以在SQL中使用一个查询或在PL/SQL中使用DBMS_OUTPUT.PUT_LINE语句来测试类库。下面是封装包的一个SQL查询,它使用了内部Java类文件:SELECT hello_world3.doDQL(SELECT character FROM mytable)FROM dual;查询返回结果如下:HELLO_WORLD3.DODQL(SELECTCHARACTERFROMMYTABLE)-Bobby McGee现在您了解了如何创建Oracle数据库存储实例Java类文件 将方法映射为P
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 合肥市老城中心区火灾韧性评估及提升策略研究
- 国有资本参股对民营企业成本粘性的影响研究
- 人体发育学理论知识考核试题及答案
- 7.2力的测量 弹力(说课稿)2024-2025学年北师大版物理八年级下册
- 离婚协议(公司股权分割)
- 2025年煤矿安全生产知识考试题及参考答案
- 小学班主任工作创新方法
- 某河道生态修复工程治理思路
- 金融机构客户关系管理系统设计
- 2025年护理学基础题库及答案医院招聘
- 2025年辽宁高考地理试卷真题答案详解讲评课件(黑龙江吉林内蒙古适用)
- 2025届上海市高考英语考纲词汇表
- 小学生生活常识教育班会
- 《艾萨克·牛顿》课件
- 演员签约剧组合同协议
- 《决策分析法DEMATEL课件》
- 装修公司投资协议书
- 大学英语四级考试大纲
- 大学国防教育与国防动员
- 数字技术赋能下的小学语文课堂创新实践
- 中药塌渍操作方法
评论
0/150
提交评论