1
、在客
户
端
软
件
开发
中使用
Thin
驱动
程序
在 开发 Java 软 件方面, Oracle 的数据 库 提供了四 种类 型的 驱动 程序,二 种 用于 应 用 软 件、 applets 、 servlets 等客 户 端 软 件,另外二 种 用于数据 库 中的 Java 存 储过 程等服 务 器端 软 件。在客 户 机端 软 件的 开发 中,我 们 可以 选择 OCI 驱动 程序或 Thin 驱动 程序。 OCI 驱动 程序利用 Java 本地化接口( JNI ),通 过 Oracle 客 户 端 软 件与数据 库进 行通 讯 。 Thin 驱动 程序是 纯 Java 驱动 程序,它直接与数据 库进 行通 讯 。 为 了 获 得最高的性能, Oracle 建 议 在客 户 端 软 件的 开发 中使用 OCI 驱动 程序, 这 似乎是正确的。但我建 议 使用 Thin 驱动 程序,因 为 通 过 多次 测试发现 ,在通常情况下, Thin 驱动 程序的性能都超 过 了 OCI 驱动 程序。
2 、 关闭 自 动 提交功能,提高系 统 性能
在第一次建立与数据 库 的 连 接 时 ,在缺省情况下, 连 接是在自 动 提交模式下的。 为 了 获 得更好的性能,可以通 过调 用 带 布 尔 值 false 参数的 Connection 类 的 setAutoCommit() 方法 关闭 自 动 提交功能,如下所示:
conn.setAutoCommit(false);
值 得注意的是,一旦 关闭 了自 动 提交功能,我 们 就需要通 过调 用 Connection 类 的 commit() 和 rollback() 方法来人工的方式 对 事 务进 行管理。
3 、在 动态 SQL 或有 时间 限制的命令中使用 Statement 对 象
在 执 行 SQL 命令 时 ,我 们 有二 种选择 :可以使用 PreparedStatement 对 象,也可以使用 Statement 对 象。无 论 多少次地使用同一个 SQL 命令, PreparedStatement 都只 对 它解析和 编译 一次。当使用 Statement 对 象 时 , 每 次 执 行一个 SQL 命令 时 ,都会 对 它 进 行解析和 编译 。 这 可能会使你 认为 ,使用 PreparedStatement 对 象比使用 Statement 对 象的速度更快。然而,我 进 行的 测试 表明,在客 户 端 软 件中,情况并非如此。 因此,在有 时间 限制的 SQL 操作中,除非成批地 处 理 SQL 命令,我 们应 当考 虑 使用 Statement 对 象。
此外,使用 Statement 对 象也使得 编 写 动态 SQL 命令更加 简单 ,因 为 我 们 可以将字符串 连 接在一起,建立一个有效的 SQL 命令。因此,我 认为 , Statement 对 象可以使 动态 SQL 命令的 创 建和 执 行 变 得更加 简单 。
4 、利用 helper 函数 对动态 SQL 命令 进 行格式化
在 创 建使用 Statement 对 象 执 行的 动态 SQL 命令 时 ,我 们 需要 处 理一些格式化方面的 问题 。例如,如果我 们 想 创 建一个将名字 O'Reilly 插入表中的 SQL 命令, 则 必 须 使用二个相 连 的 “''” 号替 换 O'Reilly 中的 “'” 号。完成 这 些工作的最好的方法是 创 建一个完成替 换 操作的 helper 方法,然后在 连 接字符串心服用公式表达一个 SQL 命令 时 ,使用 创 建的 helper 方法。 与此 类 似的是,我 们 可以 让 helper 方法接受一个 Date 型的 值 ,然后 让 它 输 出基于 Oracle 的 to_date() 函数的字符串表达式。
5 、利用 PreparedStatement 对 象提高数据 库 的 总 体效率
在使用 PreparedStatement 对 象 执 行 SQL 命令 时 ,命令被数据 库进 行解析和 编译 ,然后被放到命令 缓 冲区。然后, 每 当 执 行同一个 PreparedStatement 对 象 时 ,它就会被再解析一次,但不会被再次 编译 。在 缓 冲区中可以 发现预编译 的命令,并且可以重新使用。在有大量用 户 的企 业级应 用 软 件中, 经 常会重 复执 行相同的 SQL 命令,使用 PreparedStatement 对 象 带 来的 编译 次数的减少能 够 提高数据 库 的 总 体性能。如果不是在客 户 端 创 建、 预备 、 执 行 PreparedStatement 任 务 需要的 时间长 于 Statement 任 务 ,我会建 议 在除 动态 SQL 命令之外的所有情况下使用 PreparedStatement 对 象。
6 、在成批 处 理重 复 的插入或更新操作中使用 PreparedStatement 对 象
如果成批地 处 理插入和更新操作,就能 够显 著地减少它 们 所需要的 时间 。 Oracle 提供的 Statement 和 CallableStatement 并不真正地支持批 处 理,只有 PreparedStatement 对 象才真正地支持批 处 理。我 们 可以使用 addBatch() 和 executeBatch() 方法 选择标 准的 JDBC 批 处 理,或者通 过 利用 PreparedStatement 对 象的 setExecuteBatch() 方法和 标 准的 executeUpdate() 方法 选择 速度更快的 Oracle 专 有的方法。要使用 Oracle 专 有的批 处 理机制,可以以如下所示的方式 调 用 setExecuteBatch() :
PreparedStatement pstmt3D null;
try {
((OraclePreparedStatement)
pstmt).setExecuteBatch(30);
...
pstmt.executeUpdate();
}
调 用 setExecuteBatch() 时 指定的 值 是一个上限,当达到 该值时 ,就会自 动 地引 发 SQL 命令 执 行, 标 准的 executeUpdate() 方法就会被作 为 批 处 理送到数据 库 中。我 们 可以通 过调 用 PreparedStatement 类 的 sendBatch() 方法随 时传输 批 处 理任 务 。
7 、使用 Oracle locator 方法插入、更新大 对 象( LOB )
Oracle 的 PreparedStatement 类 不完全支持 BLOB 和 CLOB 等大 对 象的 处 理,尤其是 Thin 驱动 程序不支持利 用 PreparedStatement 对 象的 setObject() 和 setBinaryStream() 方法 设 置 BLOB 的 值 ,也不支持利用 setCharacterStream() 方法 设 置 CLOB 的 值 。只有 locator 本身中的方法才能 够 从数据 库 中 获 取 LOB 类 型的 值 。可以使用 PreparedStatement 对 象插入或更新 LOB ,但需要使用 locator 才能 获 取 LOB 的 值 。由于存在 这 二个 问题 ,因此,我建 议 使用 locator 的方法来插入、更新或 获 取 LOB 的 值 。
8 、使用 SQL92 语 法 调 用存 储过 程
在 调 用 存 储过 程 时 ,我 们 可以使用 SQL92 或 Oracle PL/SQL ,由于使用 Oracle PL/SQL 并没有什 么实际 的好 处 ,而且会 给 以后 维护 你的 应 用程序的 开发 人 员带 来麻 烦 ,因此,我建 议 在 调 用存 储过 程 时 使用 SQL92 。
9 、使用 Object SQL 将 对 象模式 转 移到数据 库 中
既然可以将 Oracle 的数据 库 作 为 一 种 面向 对 象的数据 库 来使用,就可以考 虑 将 应 用程序中的面向 对 象模式 转 到数据 库 中。目前的方法是 创 建 Java bean 作 为伪 装的数据 库对 象,将它 们 的属性映射到 关 系表中,然后在 这 些 bean 中添加方法。尽管 这样 作在 Java 中没有什 么问题 ,但由于操作都是在数据 库 之外 进 行的,因此其他 访问 数据 库 的 应 用 软 件无法利用 对 象模式。如果利用 Oracle 的面向 对 象的技 术 ,可以通 过创 建一个新的数据 库对 象 类 型在数据 库 中模仿其数据和操作,然后使用 JPublisher 等工具生成自己的 Java bean 类 。如果使用 这种 方式,不但 Java 应 用程序可以使用 应 用 软 件的 对 象模式,其他需要共享你的 应 用中的数据和操作的 应 用 软 件也可以使用 应 用 软 件中的 对 象模式。
10 、利用 SQL 完成数据 库 内的操作
我要向大家介 绍 的最重要的 经验 是充分利用 SQL 的面向集合的方法来解决数据 库处 理需求,而不是使用 Java 等 过 程化的 编 程 语 言。
如果 编 程人 员 要在一个表中 查 找 许 多行, 结 果中的 每 个行都会 查 找其他表中的数据,最后, 编 程人 员创 建了独立的 UPDATE 命令来成批地更新第一个表中的数据。与此 类 似的任 务 可以通 过 在 set 子句中使用多列子 查询 而在一个 UPDATE 命令中完成。当能 够 在 单 一的 SQL 命令中完成任 务 ,何必要 让 数据在网上流来流去的?我建 议 用 户认 真学 习 如何最大限度地 发挥 SQL 的功能
在 开发 Java 软 件方面, Oracle 的数据 库 提供了四 种类 型的 驱动 程序,二 种 用于 应 用 软 件、 applets 、 servlets 等客 户 端 软 件,另外二 种 用于数据 库 中的 Java 存 储过 程等服 务 器端 软 件。在客 户 机端 软 件的 开发 中,我 们 可以 选择 OCI 驱动 程序或 Thin 驱动 程序。 OCI 驱动 程序利用 Java 本地化接口( JNI ),通 过 Oracle 客 户 端 软 件与数据 库进 行通 讯 。 Thin 驱动 程序是 纯 Java 驱动 程序,它直接与数据 库进 行通 讯 。 为 了 获 得最高的性能, Oracle 建 议 在客 户 端 软 件的 开发 中使用 OCI 驱动 程序, 这 似乎是正确的。但我建 议 使用 Thin 驱动 程序,因 为 通 过 多次 测试发现 ,在通常情况下, Thin 驱动 程序的性能都超 过 了 OCI 驱动 程序。
2 、 关闭 自 动 提交功能,提高系 统 性能
在第一次建立与数据 库 的 连 接 时 ,在缺省情况下, 连 接是在自 动 提交模式下的。 为 了 获 得更好的性能,可以通 过调 用 带 布 尔 值 false 参数的 Connection 类 的 setAutoCommit() 方法 关闭 自 动 提交功能,如下所示:
conn.setAutoCommit(false);
值 得注意的是,一旦 关闭 了自 动 提交功能,我 们 就需要通 过调 用 Connection 类 的 commit() 和 rollback() 方法来人工的方式 对 事 务进 行管理。
3 、在 动态 SQL 或有 时间 限制的命令中使用 Statement 对 象
在 执 行 SQL 命令 时 ,我 们 有二 种选择 :可以使用 PreparedStatement 对 象,也可以使用 Statement 对 象。无 论 多少次地使用同一个 SQL 命令, PreparedStatement 都只 对 它解析和 编译 一次。当使用 Statement 对 象 时 , 每 次 执 行一个 SQL 命令 时 ,都会 对 它 进 行解析和 编译 。 这 可能会使你 认为 ,使用 PreparedStatement 对 象比使用 Statement 对 象的速度更快。然而,我 进 行的 测试 表明,在客 户 端 软 件中,情况并非如此。 因此,在有 时间 限制的 SQL 操作中,除非成批地 处 理 SQL 命令,我 们应 当考 虑 使用 Statement 对 象。
此外,使用 Statement 对 象也使得 编 写 动态 SQL 命令更加 简单 ,因 为 我 们 可以将字符串 连 接在一起,建立一个有效的 SQL 命令。因此,我 认为 , Statement 对 象可以使 动态 SQL 命令的 创 建和 执 行 变 得更加 简单 。
4 、利用 helper 函数 对动态 SQL 命令 进 行格式化
在 创 建使用 Statement 对 象 执 行的 动态 SQL 命令 时 ,我 们 需要 处 理一些格式化方面的 问题 。例如,如果我 们 想 创 建一个将名字 O'Reilly 插入表中的 SQL 命令, 则 必 须 使用二个相 连 的 “''” 号替 换 O'Reilly 中的 “'” 号。完成 这 些工作的最好的方法是 创 建一个完成替 换 操作的 helper 方法,然后在 连 接字符串心服用公式表达一个 SQL 命令 时 ,使用 创 建的 helper 方法。 与此 类 似的是,我 们 可以 让 helper 方法接受一个 Date 型的 值 ,然后 让 它 输 出基于 Oracle 的 to_date() 函数的字符串表达式。
5 、利用 PreparedStatement 对 象提高数据 库 的 总 体效率
在使用 PreparedStatement 对 象 执 行 SQL 命令 时 ,命令被数据 库进 行解析和 编译 ,然后被放到命令 缓 冲区。然后, 每 当 执 行同一个 PreparedStatement 对 象 时 ,它就会被再解析一次,但不会被再次 编译 。在 缓 冲区中可以 发现预编译 的命令,并且可以重新使用。在有大量用 户 的企 业级应 用 软 件中, 经 常会重 复执 行相同的 SQL 命令,使用 PreparedStatement 对 象 带 来的 编译 次数的减少能 够 提高数据 库 的 总 体性能。如果不是在客 户 端 创 建、 预备 、 执 行 PreparedStatement 任 务 需要的 时间长 于 Statement 任 务 ,我会建 议 在除 动态 SQL 命令之外的所有情况下使用 PreparedStatement 对 象。
6 、在成批 处 理重 复 的插入或更新操作中使用 PreparedStatement 对 象
如果成批地 处 理插入和更新操作,就能 够显 著地减少它 们 所需要的 时间 。 Oracle 提供的 Statement 和 CallableStatement 并不真正地支持批 处 理,只有 PreparedStatement 对 象才真正地支持批 处 理。我 们 可以使用 addBatch() 和 executeBatch() 方法 选择标 准的 JDBC 批 处 理,或者通 过 利用 PreparedStatement 对 象的 setExecuteBatch() 方法和 标 准的 executeUpdate() 方法 选择 速度更快的 Oracle 专 有的方法。要使用 Oracle 专 有的批 处 理机制,可以以如下所示的方式 调 用 setExecuteBatch() :
PreparedStatement pstmt3D null;
try {
((OraclePreparedStatement)
pstmt).setExecuteBatch(30);
...
pstmt.executeUpdate();
}
调 用 setExecuteBatch() 时 指定的 值 是一个上限,当达到 该值时 ,就会自 动 地引 发 SQL 命令 执 行, 标 准的 executeUpdate() 方法就会被作 为 批 处 理送到数据 库 中。我 们 可以通 过调 用 PreparedStatement 类 的 sendBatch() 方法随 时传输 批 处 理任 务 。
7 、使用 Oracle locator 方法插入、更新大 对 象( LOB )
Oracle 的 PreparedStatement 类 不完全支持 BLOB 和 CLOB 等大 对 象的 处 理,尤其是 Thin 驱动 程序不支持利 用 PreparedStatement 对 象的 setObject() 和 setBinaryStream() 方法 设 置 BLOB 的 值 ,也不支持利用 setCharacterStream() 方法 设 置 CLOB 的 值 。只有 locator 本身中的方法才能 够 从数据 库 中 获 取 LOB 类 型的 值 。可以使用 PreparedStatement 对 象插入或更新 LOB ,但需要使用 locator 才能 获 取 LOB 的 值 。由于存在 这 二个 问题 ,因此,我建 议 使用 locator 的方法来插入、更新或 获 取 LOB 的 值 。
8 、使用 SQL92 语 法 调 用存 储过 程
在 调 用 存 储过 程 时 ,我 们 可以使用 SQL92 或 Oracle PL/SQL ,由于使用 Oracle PL/SQL 并没有什 么实际 的好 处 ,而且会 给 以后 维护 你的 应 用程序的 开发 人 员带 来麻 烦 ,因此,我建 议 在 调 用存 储过 程 时 使用 SQL92 。
9 、使用 Object SQL 将 对 象模式 转 移到数据 库 中
既然可以将 Oracle 的数据 库 作 为 一 种 面向 对 象的数据 库 来使用,就可以考 虑 将 应 用程序中的面向 对 象模式 转 到数据 库 中。目前的方法是 创 建 Java bean 作 为伪 装的数据 库对 象,将它 们 的属性映射到 关 系表中,然后在 这 些 bean 中添加方法。尽管 这样 作在 Java 中没有什 么问题 ,但由于操作都是在数据 库 之外 进 行的,因此其他 访问 数据 库 的 应 用 软 件无法利用 对 象模式。如果利用 Oracle 的面向 对 象的技 术 ,可以通 过创 建一个新的数据 库对 象 类 型在数据 库 中模仿其数据和操作,然后使用 JPublisher 等工具生成自己的 Java bean 类 。如果使用 这种 方式,不但 Java 应 用程序可以使用 应 用 软 件的 对 象模式,其他需要共享你的 应 用中的数据和操作的 应 用 软 件也可以使用 应 用 软 件中的 对 象模式。
10 、利用 SQL 完成数据 库 内的操作
我要向大家介 绍 的最重要的 经验 是充分利用 SQL 的面向集合的方法来解决数据 库处 理需求,而不是使用 Java 等 过 程化的 编 程 语 言。
如果 编 程人 员 要在一个表中 查 找 许 多行, 结 果中的 每 个行都会 查 找其他表中的数据,最后, 编 程人 员创 建了独立的 UPDATE 命令来成批地更新第一个表中的数据。与此 类 似的任 务 可以通 过 在 set 子句中使用多列子 查询 而在一个 UPDATE 命令中完成。当能 够 在 单 一的 SQL 命令中完成任 务 ,何必要 让 数据在网上流来流去的?我建 议 用 户认 真学 习 如何最大限度地 发挥 SQL 的功能