按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
}
});
aFrame。add(applet; BorderLayout。CENTER);
aFrame。setSize(500;200);
applet。init();
applet。start();
aFrame。setVisible(true);
}
} ///:~
数据库的许多逻辑都是相同的,但大家可看到这里添加了一个 TextListener,用于监视在TextField (文本
字段)的输入。所以只要键入一个新字符,它首先就会试着查找数据库中的“姓”,并显示出与当前输入相
符的第一条记录(将其置入pletion Label,并用它作为要查找的文本)。因此,只要我们键入了足够的
字符,使程序能找到与之相符的唯一一条记录,就可以停手了。
15。7。3 JDBC API 为何如何复杂
阅览JDBC 的联机帮助文档时,我们往往会产生畏难情绪。特别是DatabaseMetaData接口——与Java 中看到
的大多数接口相反,它的体积显得非常庞大——存在着数量众多的方法,比如
dataDefinitionCausesTransactionmit(),getMaxColumnNameLength(),getMaxStatementLength(),
storesMixedCaseQuotedIdentifiers(),supportsANSI92IntermediateSQL(),supportsLimitedOuterJoins()
等等。它们有这儿有什么意义吗?
正如早先指出的那样,数据库起初一直处于一种混乱状态。这主要是由于各种数据库应用提出的要求造成
的,所以数据库工具显得非常“强大”——换言之,“庞大”。只是近几年才涌现出了SQL 的通用语言(常
用的还有其他许多数据库语言)。但即便象SQL 这样的“标准”,也存在无数的变种,所以JDBC 必须提供一
个巨大的DatabaseMetaData 接口,使我们的代码能真正利用当前要连接的一种“标准”SQL 数据库的能力。
简言之,我们可编写出简单的、能移植的 SQL。但如果想优化代码的执行速度,那么为了适应不同数据库类
型的特点,我们的编写代码的麻烦就大了。
当然,这并不是Java 的缺陷。数据库产品之间的差异是我们和JDBC 都要面对的一个现实。但是,如果能编
写通用的查询,而不必太关心性能,那么事情就要简单得多。即使必须对性能作一番调整,只要知道最终面
向的平台,也不必针对每一种情况都编写不同的优化代码。
在Sun 发布的Java 1。1 产品中,配套提供了一系列电子文档,其中有对 JDBC 更全面的介绍。此外,在由
Hamilton Cattel 和 Fisher 编著、Addison…Wesley 于 1997 年出版的《JDBC Database Access with Java》
中,也提供了有关这一主题的许多有用资料。同时,书店里也经常出现一些有关JDBC 的新书。
15。8 远程方法
为通过网络执行其他机器上的代码,传统的方法不仅难以学习和掌握,也极易出错。思考这个问题最佳的方
式是:某些对象正好位于另一台机器,我们可向它们发送一条消息,并获得返回结果,就象那些对象位于自
己的本地机器一样。Java 1。1 的“远程方法调用”(RMI)采用的正是这种抽象。本节将引导大家经历一些
必要的步骤,创建自己的RMI 对象。
15。8。1 远程接口概念
RMI 对接口有着强烈的依赖。在需要创建一个远程对象的时候,我们通过传递一个接口来隐藏基层的实施细
节。所以客户得到远程对象的一个句柄时,它们真正得到的是接口句柄。这个句柄正好同一些本地的根代码
连接,由后者负责通过网络通信。但我们并不关心这些事情,只需通过自己的接口句柄发送消息即可。
创建一个远程接口时,必须遵守下列规则:
(1) 远程接口必须为public 属性(不能有“包访问”;也就是说,它不能是“友好的”)。否则,一旦客户
582
…………………………………………………………Page 584……………………………………………………………
试图装载一个实现了远程接口的远程对象,就会得到一个错误。
(2) 远程接口必须扩展接口 java。rmi。Remote。
(3) 除与应用程序本身有关的违例之外,远程接口中的每个方法都必须在自己的throws 从句中声明
java。rmi。RemoteException。
(4) 作为参数或返回值传递的一个远程对象(不管是直接的,还是在本地对象中嵌入)必须声明为远程接
口,不可声明为实施类。
下面是一个简单的远程接口示例,它代表的是一个精确计时服务:
//: PerfectTimeI。java
// The PerfectTime remote interface
package c15。ptime;
import java。rmi。*;
interface PerfectTimeI extends Remote {
long getPerfectTime() throws RemoteException;
} ///:~
它表面上与其他接口是类似的,只是对Remote 进行了扩展,而且它的所有方法都会“掷”出
RemoteException (远程违例)。记住接口和它所有的方法都是public 的。
15。8。2 远程接口的实施
服务器必须包含一个扩展了UnicastRemoteObject 的类,并实现远程接口。这个类也可以含有附加的方法,
但客户只能使用远程接口中的方法。这是显然的,因为客户得到的只是指向接口的一个句柄,而非实现它的
那个类。
必须为远程对象明确定义构建器,即使只准备定义一个默认构建器,用它调用基础类构建器。必须把它明确
地编写出来,因为它必须“掷”出 RemoteException 违例。
下面列出远程接口PerfectTime 的实施过程:
//: PerfectTime。java
// The implementation of the PerfectTime
// remote object
package c15。ptime;
import java。rmi。*;
import java。rmi。server。*;
import java。rmi。registry。*;
import java。*;
public class PerfectTime
extends UnicastRemoteObject
implements PerfectTimeI {
// Implementation of the interface:
public long getPerfectTime()
throws RemoteException {
return System。currentTimeMillis();
}
// Must implement constructor to throw
// RemoteException:
public PerfectTime() throws RemoteException {
// super(); // Called automatically
}
// Registration for RMI serving:
583
…………………………………………………………Page 585……………………………………………………………
public static void main(String'' args) {
System。setSecurityManager(
new RMISecurityManager());
try {
PerfectTime pt = new PerfectTime();
Naming。bind(
〃//colossus:2005/PerfectTime〃; pt);
System。out。println(〃Ready to do time〃);
} catch(Exception e) {
e。printStackTrace();
}
}
} ///:~
在这里,main()控制着设置服务器的全部细节。保存RMI 对象时,必须在程序的某个地方采取下述操作:
(1) 创建和安装一个安全管理器,令其支持RMI。作为Java 发行包的一部分,适用于RMI 唯一一个是
RMISecurityManager 。
(2) 创建远程对象的一个或多个实例。在这里,大家可看到创建的是PerfectTime 对象。
(3) 向RMI 远程对象注册表注册至少一个远程对象。一个远程对象拥有的方法可生成指向其他远程对象的句
柄。这样一来,客户只需到注册表里访问一次,得到第一个远程对象即可。
1。 设置注册表
在这儿,大家可看到对静态方法Naming。bind() 的一个调用。然而,这个调