📄 0024.htm
字号:
和 表 的 名 称 来 识 别 那 些 可 以 处 理 从 表 中 抽 取 出 的 记 录 的 构 造 函 数。 利 用 标 准 的JDBC 类, 可 以 容
易 地 获 得 所 有 表 的 表 名, 在 此, 我 们 将 要 充 分 利 用 这 个Java 小 技 巧。 只 要 简 单 地 为 每 个 数 据 库 表
开 辟 一 个Java 类, 使 类 名 和 表 名 相 互 匹 配, 无 论 何 时, 每 当 从 表 中 抽 取 出 一 条 记 录 的 时 候, 通 过
将 表 名 传 递 给Class.forName(), 程 序 将 自 动 生 成 一 个 对 象。 </P><PRE> Class c = class.forName("Person");
Person p = (Person)c.newInstance();
System。out.println("... just created a " + c.getName();
</PRE>
<P>清 单2: 一 个 简 单 的Class.forName() 例 子 </P>
<P> 然 而, 此 处 还 有 一 些 问 题。 由 于 对
某 些 特 定 的 类 来 说,forName() 函 数 需 要 调 用 参 数 为void 的 构 造 函 数, 所 以 不 能 将RecordSet 变
量 直 接 传 递 给 构 造 函 数。 在 这 里, 我 们 需 要 一 个 初 始 化 函 数, 把 从 数 据 库 中 抽 取 出 的 记 录 作
为RESULTSET 参 数, 将 其 值 赋 予 对 象 的 数 据 元 素。 一 个 好 的 方 法 是 引 入 超 级 类, 并 将 其 作 为 所 有
数 据 库 表 相 关 类 的 通 用 父 类。 实 际 上, 这 个 超 级 类 在 数 据 库 查 询 中 充 当 着 重 要 的 角 色, 我 们 将 在
下 面 展 示 这 一 点。 </P>
<H3>查 询 数 据 库</H3>
<P> 利 用 上 面 的 方 法 可 以 由 记 录 生 成
对 象, 但 是 你 仍 然 得 用SQL 语 句 来 查 询 数 据 库, 这 需 要 对 数 据 库 结 构 有 深 入 的 了 解。 这 还 是 没 有
解 决 问 题, 虽 然 我 们 能 够 自 动 地 匹 配 数 据 库 表 和 类 的 名 字, 但 是 还 是 必 须 手 工 编 写SQL 语 句。 这
就 是 说 每 次 修 改 数 据 库 结 构 后, 将 不 得 不 手 工 编 辑 这 些 查 询 语 句。 不 过, 我 们 仍 然 可 以 利 用 前 文
所 述 的 方 法 来 越 过 这 个 障 碍。 通 常 而 言, 查 询 关 系 数 据 库 时, 你 将 会 用 到 属 于 主 键 或 索 引 的 字 段
名 和 值。 一 言 弊 之, 如 果 某 人 向 你 提 供 了 适 当 的 字 段 名 和 字 段 值, 你 就 可 以 从 相 应 的 数 据 库 中 抽
取 符 合 要 求 的 记 录( 或 字 段)。 而DatabaseMetaData 对 象 不 但 可 以 被 用 于 检 索 一 系 列 的 表 名( 见
上 所 述), 而 且 可 以 获 得 一 系 列 的 主 键 及 索 引 字 段。 上 面 的 问 题 由 此 可 以 迎 刃 而 解。 </P>
<P> 通 过 填 入 一 系 列 适 当 的( 字 段 名,
字 段 值) 对, 可 以 利 用 相 对 而 言 少 得 多 的 代 码 实 现 对 关 系 数 据 库 的 查 询。 你 可 以 将 对 子 中 的 所 有
字 段 名 和 数 据 库 中 的 主 健 及 索 引 字 段 相 匹 配。 每 当 你 找 到 了 名 字 列 表 中 相 应 的 主 健 或 索 引 字
段, 可 以 根 据 相 应 的 数 值 来 生 成 一 个SQL 语 句, 执 行 它 来 获 取RecordSet, 并 通
过Class.forName() 构 造 机 制 将 结 果 转 化 为 对 象。 </P>
<P> 实 现 这 一 想 法 要 求 可 以 以( 名, 值)
对 的 方 式 对 与 数 据 库 表 相 关 的 每 个 类 的 数 据 元 素 进 行 存 取。 但 是 这 种 方 法 只 有 通 过 上 节 所 述 的
通 用 父 类 才 能 趋 于 完 美。 清 单3 和4 利 用 伪 码 表 示 了 这 一 方 法。 </P><PRE> Open the database connection
Retrieve a list of user defined tables
for each table
{
Check where there is a corresponding class file
if(it is availabe)
{
load the class file
Retrieve lists of key fields and indeces for this table
Store these lists in hashtables for easy access
}
else throw an exception
}
清 单3: 初 始 化 数 据 库 连 接 的 伪 码
Take an object A containing a series of (name,value) pairs
for each table T
{
for each (name,value) pair
{
if(name matches primary_key_field or index_field)
store a refrence to both name and value
}
if all key_fields were found
create a query string using key names and values
else if all index_fields were found
create a query string using index names and values
execute the query to obtain a ResultSet
For each record in the ResultSet
{
Create an object of the class associated with table T
initialize the object using the record''s contents
Add the object to the results, e。g。, attach it to A
}
}
</PRE>
<P>清 单4: 描 述 数 据 库 查 询 的 伪 码 </P>
<H3>Java 镜 像 和Javabeans</H3>
<P> Java1.1 开 发 套 件(JDK) 的 引 入,
为 我 们 带 来 了 许 多 强 大 的 新 性 能, 例 如 全 新 的 用 户 界 面 接 口 类。 有 两 个 新 的JDK API 尤 其 值 得 注
意: 镜 像 机 制(java.lang.reflect 包) 和JavaBeans 组 件 的 应 用 程 序 接 口(java.beans 包)。 这 两
个API 将 会 帮 助 我 们 创 建 高 明 的 数 据 库 类, 使 我 们 可 以 利 用 有 关 类 的meta- 信 息, 以 此 来 解 决 开
发 通 用 数 据 库 类 中 的 问 题。 </P>
<P> 拥 有forName() 和newInstance()
方 法 的Class 类, 仅 仅 是 镜 象(reflection) 功 能 的 一 个 简 单 例 子。 真 正 重 要 的 是,forName() 字 符
串 参 数 不 必 须 是 源 程 序 中 出 现 的 字 符 串。 只 要 给 出 一 个 名 字 ( 这 个 名 字 可 从 任 何 地 方 取 来 ),
你 就 可 以 载 入 并 实 例 化 任 何 一 个 类。 对 于 我 们 的 数 据 库 类, 我 们 可 以 直 接 从 数 据 库 自 身 的 表 名
中 得 到 类 名。 这 就 是 说, 与 数 据 库 表 相 关 的Java 类 名 并 不 需 要 出 现 在 源 程 序 中。 相 应 地, 当 表 名
改 变 或 某 个 表 被 加 入 到 数 据 库 中 时, 不 需 要 修 改 源 码, 只 要 确 信 带 有 新 名 字 的 类 已 存 在 你 的 系
统 中。 </P>
<P> 镜 像 类 意 味 着 可 以 在 实 时 运 行 中
获 取、 存 储 和 处 理Java 程 序 中 的 类 信 息。 它 们 的 实 例 能 够 象 任 何Java 对 象 一 样 被 运 用, 你 可 以 象
修 改 字 符 串 和 整 数 一 样, 去 修 改 类、 数 据 类 型、 返 回 类 型、 方 法 参 照 和 参 数。 在 源 程 序 级, 这 个 镜
像 的 概 念 看 起 来 并 没 有 什 么 价 值 — — 因 为 可 以 应 用 你 自 己 的 编 码 直 接 存 取 你 所 需 要 的 有 关 类、
方 法 及 参 数 的 所 有 信 息。 但 是, 镜 像(reflection) 将 会 在java 的 编 译 文 件 中 发 挥 作
用。JavaBeans API 的 作 用 是: 通 过 应 用 程 序 的 构 造 机 制 利 用 来 自 于 全 然 不 同 的 开 发 者 或 产 商 所
编 写 的 类。 </P>
<P> JavaBeans 规 范 为 类 成 员 的 名 字
制 定 一 系 列 的 条 例。 以 确 保 方 法 函 数 的 名 字 能 系 统 地 描 述 它 们 的 功 能。 任 何 一 个 符 合 规 则
的Java 类 都 可 以 被 一 个Bean 的 内 化 实 例( 通 过 镜 像) 检 查, 以 揭 示 其 行 为 的 重 要 特 征 — — 诸 如 对
于 什 么 样 的 事 件 类 将 有 所 响 应, 以 及 该 类 将 会 产 生 什 么 样 的 事 件 等 等。 任 何 符 合 这 些 规 范 的 类
都 是 高 效 的Bean, 因 而 是 一 个 组 件。 在 理 论 上, 这 意 味 着 你 可 以 从 各 种 来 源 收 集 一 系 列beans, 当
需 要 它 们 时 可 以 将 其 其 实 时 地 绑 在 一 起。 </P>
<H3>一 个Bean 的 例 子</H3>
<P> 在 下 面 一 个 名 为Translation
的Bean 中, 有 一 个 构 造 函 数 和 两 个 方 法 来 操 作 一 个 名 为“language” 的 属 性。 这 里 我 想 强 调 的 是,
既 然 你 可 以 通 过 检 查 一 个 类 的 代 码 来 了 解 它 的 构 造 函 数、 方 法 及 属 性, 那 么Bean 的 内 化
器(Introspector) 也 能 做 到。 </P><PRE> public class Translation extends Object
{
int language;
public translation()
{
}
public int getlanguage()
{
return(language);
}
public void setLanguage( int language)
{
this。language=language;
}
}
</PRE>
<P>清 单5: 一 个 非 常 简 单 的Bean </P>
<P> 一 个Bean Introspector 能 够 提 供
许 多 数 组 的PropertyDescriptor 实 例, 这 些 实 例 包 含 所 有Bean 的 属 性 的 类 型 信 息, 即 例 子 中
由get/set 方 法 所 定 义 的 类 型。 你 可 以 调 用 这 些 方 法( 利 用reflection) 来 读 或 写 这 些 属 性。
</P>
<P> 镜 像 机 制(reflection
facilities) 为 我 们 检 查 原 本 松 散 的 类 和 数 据 库 表 的 完 整 性 提 供 了 的 更 好 方 法。 实 际 上, 仅 仅
通 过 类 名 和 一 个 表 匹 配 并 不 一 定 能 够 保 证 一 些 类 内 部 的 一 致 性。 一 个 与 表 相 关 的 类 显 然 应 当 具
备 存 储 数 据 库 表 中 所 有 字 段 的 数 据 元 素。 一 个 类 可 能 有 适 当 的 名 字, 但 其 初 始 化 代 码 可 能 会 省
略。 它 可 能 只 有 一 个 正 确 的 名 字, 而 其 数 据 成 员 可 能 有 不 同 的 名 字 或 者 是 不 同 的 类 型。 使 用JDBC
的DatabaseMetaData 及 镜 像 机 制 可 以 检 查 它 们 是 否 完 全 匹 配 ! </P>
<P> 引 用 一 些JDBC 调 用 去 获 得 现 实 中
必 须 的 数 据 库 信 息, 通 过 正 确 的 名 字 去 检 查 你 系 统 中 的 类, 并 且 通 过 镜 像 去 比 较 表 和 类 的 属 性,
这 实 实 在 在 是 一 块 香 饼 ! </P>
<H3>结 论 和 启 示</H3>
<P> JDBC, 镜 像 和JavaBeans 三 者 的 结
合, 能 够 方 便 地 从 关 系 数 据 库 中 存 取 记 录 并 利 用 记 录 来 初 始 化 组 件( 不 仅 仅 是 对 象)。 为 了 实 现
上 述 操 作, 无 需 修 改 你 的 数 据 库, 只 需 确 认 你 的 类 符 合Bean 规 范, 并 使 类 属 性 和 表 字 段 相 互 匹
配。Beans 还 有 其 它 一 些 简 单 的 技 巧, 可 使 编 程 更 加 有 趣。Beans 能 够 提 供 自 己 的 用 户 界 面 组 件,
并 且Beans 规 范 还 包 括 一 个 名 为Customizers 的 东 西。 你 可 以 引 入 另 外 的 类 专 门 地 去 察 看、 编 辑
和 自 行 定 制 一 个Bean 类 的 实 例。( 关 于 定 制Beans, 请 参 看 下 一 期《 定 制 你 的Java》 </P>
<P> 总 之, 我 们 可 以 为 数 据 库 类 编 写 自
行 定 义 的 类, 应 用 程 序 能 够 从 关 系 数 据 库 中 抽 取 数 据, 通 过 实 例 化 某 个 类 得 到 新 的 实 例, 并 引 入
相 关 的 图 形 用 户 界 面(GUI) 组 件 来 查 看 和 编 辑 数 据。 所 有 这 些 都 由 通 用 代 码 完 成, 因 而 能 够 处 理
任 何 数 据 库。 利 用Java 编 写 的、 功 能 齐 全 的 数 据 库 查 看/ 编 辑 器 正 迎 我 们 而 来。 </P>
<P> 张 智 雄 编 译 </P>
<P> 稿 件 来
源:http://www.javaworld.com/javaworld/jw-09-1997/jw-09-reflections.html </P>
</table>
<p align="center"><script src="../../2.js"></script></a>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -