快捷搜索:

JDBC编程基础

1. 先容

许多开拓者和用户都在探求Java法度榜样中造访数据库的便捷措施。因为Java是一个壮实,安然,易于应用的,易于理解且可以从收集中自动download ,以是它成为开拓数据库利用的一种优越的说话根基。它供给了C,C ,Smalltalk, BASIC, COBOL, and 4GLs的许多优点。许多公司已经开始在Java与DBMS的连接方面干事情。

许多Java利用开拓者都盼望能够编写自力于特定DBMS的法度榜样,而我们也信托一个自力于DBMS的接口将使得与各类各样DBMS连接变得最为便捷,开拓加倍迅速。以是我们觉得定义一个通用的SQL数据库存取框架,在各类各样的供给数据库连接模块上供给统一的界面是十分故意义的。这使法度榜样员可以面对单一的数据库界面,使数据库无关的Java对象和产品成为可能,使得数据库连接的开拓者可以供给各类各样的连接规划。我们看到我们定义一个通用低层的,支持基础SQL功能的Java DataBase Connectivity (JDBC)API的紧迫义务。

幸运的是我们不必从头设计一个SQL API。我们可以把我们的事情建立在 X/Open SQL CLI (调用层接口)之上(它也是Microsoft´s ODBC 的根基)。

我们主要义务是定义一个自然的Java接口来与X/Open CLI中定义的基础的抽象层和观点连接。

JDBC API获得数据库开拓厂商,连接开拓厂商,ISV,以及利用开拓者的支持是十分紧张的。我们信托把我们的事情建立在ODBC抽象层的根基上将JDBC加倍轻易获得大年夜家的吸收。而且从技巧上来说,ODBC是我们设计事情的一个优越根基。

由于ODBC是一个C说话接口,以是ODBC在Java中直接应用不适当。从Java中来调用C代码在安然性,壮实性,实现的方便,可移植性等等方面有许多不便。它使得Java在这些方面的许多优点得不到发挥。

我们已经在短期里面实现了一个建立在ODBC上的API。长远来看,我们可以经由过程其他要领供给实现。

1.1. 留意

我们异常谢谢在数据库,数据库连接和数据库对象领域的许多早期的事情者。他们为JDBC的早期草案供给了很好的意见和建议。他们的工作对本规范起了弗成估量的感化。

2. 目标与哲学

这个部分描述了指引这个API开拓的目标以及哲学。

2.1. SQL 级 API

我们的主要目标是为Java定义一个“调用级”(call-level)的SQL接口。着意味着我们主要的留意力集中在履行原蓝本本的SQL语句并且取回结果。我们估计高层的API也将被定义,这些可能将建立在基层的接口上。这些高层接口包括象直接地、透明地把内外貌的数据暗射到Java类里面,用语法树表示加倍通用的查询,以及Java内嵌的SQL语法。

我们盼望大年夜量的利用开拓对象将应用我们的API。然而我们也盼望法度榜样员能够应用我们的API,尤其是今朝这样在Java里没有任何其他手段(应该是说数据库造访手段)的环境下。

2.2. 遵照SQL

数据库系统支持种种各样的SQL语法和语义,它们互相之间在对照高档的功能例如外部连接,内嵌历程等方面并不同等,只管我们能够渴望着随光阴的推移这些部分的SQL可以得到标准化。同时我们采取这样的立场与态度:

In fact, an application query need not even be SQL, or it may be a specialized derivative of SQL, e.g. for document or image queries, designed for specific DBMSs.In order to pass JDBC compliance tests and to be called "JDBC COMPLIANT ?" we require that a driver support at least ANSI SQL-2 Entry Level. This gives applications that want wide portability a guaranteed least common denominator. We believe ANSI SQL-2 Entry Level is reasonably powerful and is reasonably widely supported today.

JDBC容许查询表达式直接通报到底层的数据驱动,这样一个法度榜样可以得到只管即便多的SQL功能,然则可能被DBMS回绝。事实上,一个法度榜样的查询以致可以不是SQL的,或者是SQL的一个特殊演化,例如:为专门数据库设计的文本或者图形查询。

为了经由过程JDBC兼容的测试,并且能够被称为JDBC兼容,我们要求一个驱动至少支持ANSI SQL-2的标准。这使得那些必要广泛移植性的法度榜样得到一个最小的分母(这句话的原文是:

This gives applications that want wide portability a guaranteed least common denominator.)。

我们信托ANSI SQL-2是足够强大年夜的,并且是获得足够支持的。

2.3. JDBC必须可以建立在现有的数据库接口上

我们必须能够包管 JDBC SQL API 能够建立在通俗的SQL API上,尤其是ODBC。这些要求已经对这个规范的一些部分孕育发生了影响,尤其是对传出参数(OUT parameter)和大年夜数据块的处置惩罚。

2.4. 必须包管这个接口与JAVA系统的其他部分维持同等

今朝对JAVA的积极回应已经十分热烈。很大年夜程度上是因为这个说话标准以及标准运行时库被觉得是同等,简单和强大年夜的。我们将尽我们所能,供给这个Java数据库接口,这个接口将建立在Java内核现有的这种风格,并且将进一步加强它。

2.5. 维持简单

We would prefer to keep this base API as simple as possible, at least

initially. In general we would prefer to provide a single mechanism for performing a particular task,and avoid provid-ing duplicate mechanisms. We will extend the API later if any important functionality is miss-ing.

我们将力图使得基础的API只管即便简单,至少开始的时刻是这样的。一样平常来说,我们盼望对实现每个特定的义务只供给一种规划,而避免供给多种规划。假如一些紧张的功能漏掉了,那么我们在晚些时刻将扩充这个API。

2.6. 只管即便维持强的、静态的类型

我们盼望这个JDBC API维持只管即便强的类型反省,使得尽可能多的类型信息可以静态地表达。着使得尽可能多的差错可以在编译的时刻被发明。

因为SQL本身是动态类型的,以是我们可能会在法度榜样运行的时刻碰到类型不能匹配的问题。例如:

当一个法度榜样员在盼望SELECT返回一个整数,然则实际返回的是一个字符串“foo”.然则我们依然盼望法度榜样员把他们所盼望的类型在编译的时刻就能够表达清楚,这样我们可以做尽可能多的静态反省。我们也盼望在需要的时刻能够支持动态类型接口(见第四章)

2.7. 使通俗义务简化

我们盼望通俗的义务能够是简单的,而不一样平常的事情是可行的。

一个通俗义务是指一个法度榜样员履行一个简单的没有参数的SQL语句(例如:SELECT,INSERT,UPDATE,DELETE),然后(例如SELECT)处置惩罚返回的具有简单类型的元组。一个具有传入参数(IN parameter)的SQL语句也是通俗的。不那么通俗然则也是十分紧张的情形是当法度榜样员应用有INOUT,OUT参数的SQL语句。我们

也必要支持读写几兆字节工具的SQL语句,更分外一些的情形包括一个语句返回了多个结果聚拢。

我们盼望元数据(Meatdata)的应用很少的,只是那些纯熟的法度榜样员以及开拓对象才必要处置惩罚的问题。元数据存取函数以及动态类型数据存取函数在这个文档末端,一样平常的法度榜样员可以不必关心这些章节。

2.8. 不合的功能让不合的措施(函数)来实现

(“措施”的原文是:method,这样翻译是跟VB的)一种界面设计风格是应用很少的历程,供给许多作为参数通报的节制标志,这样它们可以用来影响很大年夜一个范围内的各类行径。来表达不合的功能。这趋向与应用很多的措施,然则每个措施都对照批准理解。

一样平常来说,Java内核类应用不合的措施(method)。这个步骤的主要优点是开始进修基础界面的法度榜样员可以不必被那些与繁杂功能相关的参数所困扰。我们力求在JDBC接口上也采纳相同的策略。一样平常来说采纳不合的措施而不是采纳不合的标志和多用途的措施。

3. 接口概貌

接口分为两个层次,一个是面向法度榜样开拓职员的JDBC API。别的一个是底层的JDBC Driver API。

3.1. JDBC API

JDBC API 被描述成为彝族抽象的Java接口,似的利用法度榜样远可以对某个数据库打开连接,履行SQL语句并且处置惩罚结果。差错! 嵌入工具无效。

最紧张的接口是:

java.sql.DriverManager 处置惩罚驱动的调入并且对孕育发生新的数据库连接供给支持。

java.sql.Connection 代表对特定命据库的连接。

java.sql.Statement  代表一个特定的容器,来对一个特定的数据库履行SQL语句。

java.sql.ResultSet  节制对一个特定语句的行数据的存取。此中java.sql.Statement又有两个子类型:

1. java.sql.PreparedStatement  用于履行预编译的SQL语句。

2. java.sql.CallableStatement  用于履行对一个数据库内嵌历程的调用。

下面的章节对JDBC是若何运行的供给了更多描述,全部定义见第13章。别的第15章描述了系统假如获取数据库的元数据信息。

3.2. JDBC Driver API

java.sql.Driver在第9章有完备的定义了.大年夜部分JDBC驱动只必要完成这些JDBC API所定义的抽象类就可以了。分外埠,所有的driver必须供给对java.sql.Connection,java.sql.State-ment, java.sql.Prepared-Statement, and java.sql.ResultSet的实现。假如目标DBMS供给有OUT参数的内嵌历程,那么还必须供给java.sql.CallableStatement 接口。

每个database driver必须供给一个类:java.sql.Driver以使得系统可以由java.sql.DriverManager来治理。

一个显然的driver是在ODBC之上供给对JDBC的实现,从而供给与ODBC接口的JDBC-ODBC 桥,就象前面的图所显示的.因为JDBC放在ODBC之后,以是实现起来简单而且高效。别的一个有用的驱动直接打仗数据库无关的收集协议。宣布一个协议允许多个办事器实现的措施,例如在ODBC或者特定的DBMS上(只管已经有了一些应用固定协议的产品,然则我们不盘算对它们实现标准化。),是可取的。

4. JDBC应用处合

Before looking at specifics of the JDBC API, an understanding of typical use scenarios is help-ful. There are two common scenarios that must be treated differently for our purposes: applets and applications.

在看JDBC API之前懂得一下范例的应用处合是有赞助的。平日有两种情形必须分手对待:applet和application.

4.1. Applet

今朝Java应用的最多的从收集中下载的applet,它们作为web文件的一个部分。傍边稀有据库存取applet和能够应用JDBC来打仗数据库的applet。

例如,一个用户可能下载一个显示股票历史价格图的applet。这个applet经由过程internet来从关系数据库中得到股票历史价格。最一样平常的环境里面,对applet的应用是经由过程弗成靠的界限的。例如从别的一个公司或者Internet上得到这些applet。于是称这个环境为"Internet"场合。然而applet也可能经由过程局域网下载。在这个环境里面,客户机的安然都照样一个问题。

范例的applet在几个方面与传统的数据库利用法度榜样有所不合:

1. 弗成靠的applet被严格地限定在他们被容许履行的的操作上。分外埠,不容许他们存取本地的文件,切不容许他们对随意率性的数据库建立收集连接。

2. 就标识和连接网上数据库来说,Internet情况里面的applet面临新的问题。

3. 当数据库可能与你相隔万里的时刻,效率的斟酌也有所不合了。与局域网比拟,Internet上数据库applet可能会碰着十分不合的反映光阴。

4.2. Application

Java也可以用来建立通俗的利用,从而想一样平常的利用一样在客户机上应用。我们信托跟着开拓对象越来越多,人们开始熟识到前进法度榜样临盆效率的需要性,以及Java的其他优点,Java的这种用法将越来越盛行。在这种要领里面,Java的代码是可以信赖的,且被容许读写文件打开收集连接等等,就想其他的利用法度榜样代码一样。

大概这些Java利用应用的最多的是在一个公司内部或者在Intranet上,以是不妨成为Intranet场合。例如一个公司盼望使用Java及其GUI构件对象来建立他的基于相助数据模式的相助软件。这些利用法度榜样将存取局域网或者广域网的数据。Java利用可以作到这些。

Java利用法度榜样场合和Intranet场合与applet场合有诸多不合。例如标定一个数据库最自然的要领是用一个数据库的名字,就象"Customers" 和"Personnel"这样。然后用户盼望系统能够定位详细的机械,DBMS,JDBC driver,和Java利用法度榜样。

4.3. 其他场合

还有其他一些有趣的场合:

1. 已验证的applet(Trusted applets)是指那些已经被Java虚拟机械认定是可以信赖的applet。他们之以是被觉得是可托的是由于他们已经对上了特定的密匙,或者用户觉得从特定滥觞来的applet是可托的。在安然的方面上他们与利用(appliction)相同,然则其他方面(例如定位一个数据库)与则与applet相似。

2. 与直接从Java GUI启程用客户/办事器模式来度曲DBMS办事器不合,三层存取要领可能被应用。在这个场合里面,Java利用法度榜样对中心层的办事发出调用,中心层的办事在网上,它又再去调用数据库。这些调用可能经由过程RPC (remote procedure call)或者ORB (object requestbroker )。在这两种场合里面,中心层最好应用一个工具变更。我们盼望三层布局会变得越来越普遍,由于对付MIS治理者来说,这可以使得他们有时机在公共数据库上显式地定义合法操作等。同时三层布局可以供给许多效率上的好处。

今朝中心层一样平常用C或者C 这样的说话来完成。经由过程优化编译器把把Java 字节代码翻译成为高效的机械代码,中心层也可以用Java来实现。Java有许多精良特点(壮实性,安然性,多线程)可以达到中心层必要达到的目的。

5. 安然性斟酌

作为收集上的说话JAVA必须十分注安然性的斟酌。基于上面的评论争论,JDBC的两种主要应用处合里面,我们必须斟酌安然性问题:

在Java applications的场合里面Java代码是本地的,以是也是"trusted",没有验证的Java applet代码弗成以存取本地的以及其他收集的数据。

5.1. JDBC 和未验证的applet

JDBC首先必须相符JAVA的一样平常安然规则。别的:

JDBC 必须觉得没有验证的applets是弗成靠的。l JDBC 弗成以让弗成靠的applets存取本地数据库。

一个已经向JDBC DriverManager注册的是JDBC Driver只能存取它所来的数据源。

一个applet也只能向它所Download来的办事器来存取数据。

假如JDBC驱动层假如完全确信对一个数据库办事器打开连接不会引起认证或者权限问题(可能由网上随机主机上运行的法度榜样引起),那么它就容许applet打开这样的连接。数据库办事器不经由过程IP地址来限定存取是相称少的,主如果为了举例。(警惕,这一段话我可能翻译反了!!!大年夜家看看原文。)这些限定是相称啰嗦的。不过他们与对一样平常applet的限定是同等的我们没有需要摊开这些限定。

5.2. JDBC 和Java利用法度榜样

对付一个通俗的Java利用法度榜样(例如整个用Java代码而不是弗成靠的applet )JDBC将从本地的类路径里面得到驱动,并且容许利用法度榜样自由存取文件,远程办事器等等。然则和applet一样,假如因为某些缘故原由一个没有验证的sun.sql.Driver类从远程的滥觞里面得到,那么这个驱动只能和相同地方来的代码共同。

5.3. Driver的安然责任

JDBC driver可能在各类环境下应用,以是驱动的体例者遵照必然的简单的安然规则,从而避免applet做不法的数据库连接。假如所有的驱动都象applet一样从网高低载,那么这些原则将是不需要的,由于通俗的安然规则已经对它做了限定。然则驱动的编写者必须记着一旦他们的驱动得到成功,用户将在本地磁盘安装这些驱动,那么驱动将成为Java情况中一个被相信的部分,以是必须确信它不会被来访的applet所滥用。以是我们鼓励所有的驱动编写者必须遵照必然安然原则。

所有这些原则都是在连接打开的时刻应用。这正式驱动和虚拟机械反省当前调用者是否真的可以与指定的数据库连接的时候。一旦连接建立就不必做更多的反省了。

5.3.1. 分享TCP/IP连接的时刻必须审慎

假如一个JDBC驱动试图打开一个 TCP 连接,那么这个打开会被Java 安然治理机制自动反省。这个机构会反省当前调用栈里面有没有applet,假如有那么就限制它可以造访的机械聚拢。以是一样平常地JDBC驱动可以把TCP建立反省留给Java虚拟机。然则假如一个JDBC驱动试图在多个数据库连接之间共享一个TCP连接,那么驱动就必须自己认真反省每个调用者是否真的被容许与目标数据库联系。例如假如我们为applet A打开了一个通往机械foobah 的TCP连接,这并不料味着applet B被自动容许来共享这个连接。applet B可能没有任何造访机械foobah的权力。以是在容许某个法度榜样重用一个现成的TCP连接之前,JDBC 驱动必须经由过程安然机构来反省当前的的调用者是否可以造访这个连接。经由过程下面的代码可是实现这个功能。

SecurityManager security = System.getSecurityManager();

if (security != null)

{

security.checkConnect(hostName, portNumber);

}

假如连接是不容许的,那么Security.checkConnect措施将孕育发生一个java.lang.SecurityException。

5.3.2. 反省所有的本地文件造访

假如一个JDBC取得必要造访本地机械上的数据,那么他必须确信调用者是被容许打开这个文件的。例如:

SecurityManager security = System.getSecurityManager();

if (security != null)

{

security.checkRead(fileName);

}

假如对特定文件的造访是不容许的,那么Security.checkRead措施将孕育发生一个java.lang.SecurityException。

5.3.3. 作好最坏的筹备

一些驱动可能应用本地的措施来桥接底层数据库法度榜样。则这些环境里面判断那些本地文件将被底层函数所造访是艰苦的。在这些情况里面用户必须作好最坏的盘算,并且反对所有下载applet所发出的数据库存取,除非驱动可能完全确信将要做存取是没有问题的。

例如一个JDBC-ODBC桥接器必须反省ODBC数据源的的名称,确保applet只可以造访它的“生源地”。假如对有的名字中不能判断出数据源的主机名,那么只能反对这个造访。为了抉择一个当前的调用者是可以信赖的利用照样一个applet,JDBC驱动必须能够反省这个调用者是否可以写一个随机的文件:

SecurityManager security = System.getSecurityManager();

if (security != null)

{

security.checkWrite("foobaz");

I. }

您可能还会对下面的文章感兴趣: