Java开发网 Java开发网
注册 | 登录 | 帮助 | 搜索 | 排行榜 | 发帖统计  

您没有登录

» Java开发网 » 技术文章库  

按打印兼容模式打印这个话题 打印话题    把这个话题寄给朋友 寄给朋友    该主题的所有更新都将Email到你的邮箱 订阅主题
flat modethreaded modego to previous topicgo to next topicgo to back
作者 提示和技巧:JDBC 提示
palatum



CJSDN高级会员


发贴: 451
积分: 80
于 2003-01-04 09:52 user profilesend a private message to usersend email to palatumsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
提示和技巧:JDBC 提示
改进您的动态的移动应用程序

Roman Vichr(rvichr@ddlabs.com)
高级设计师,DDLabs
2003 年 1 月

我们己经讨论了如何使您的应用程序接口更健壮并具有更好的动态性,还讨论了如何为移动应用程序过滤内容。现在我们需要重点讨论的是:当通过 HTTP 将企业数据推到移动设备应用程序时,怎样对数据库连接进行优化以获得最佳结果(请参阅参考资料链接到最近的 developerWorks 文章,该篇文章提供了更多信息。)

企业数据库连接性的恰当构建是非常重要的,并且在为有限连接设备配置(Connection Limited Device Configuration(CLDC))构建应用程序和编写特定于 MIDP(移动接口)的接口之间,哪一种是最佳选择取决于 J2ME 和 Java 技术。

方式
介绍在把企业数据桥接到无线移动设备时建立 JDBC 连接的一条简单原则,这可以帮助您使解决方案具有更好的可扩展性和更高效的性能。

连接池
任何应用程序都必须先访问活动的数据库连接,然后才能访问数据库。数据库连接是一个很占资源且 I/O 开销很大的操作,并且如果每次想使用数据库连接时都必须创建它,那么它将会成为您的性能瓶颈。

例如,如果您使用 Java servlet(Java servlet 通过 init() 方法创建并在其生命周期结束时被销毁(通过 destroy() 方法))的方式,您是虽然避免了每次 servlet 被实例化时重新建立连接。这样一种方式会明显地降低应用程序的性能。完成相同功能的更好的途径是使用“连接池(Connection Pool)”,您可以在连接池中初始化多个连接(并且参数可以从 XML 配置文件中读取)。

连接本身由一组集合对象和一个在整个请求过程中使连接保持打开的用户请求组成。创建连接池的关键是在数据库访问代码中使用如下一些块:try{}.. catch{}... finally{}..。然后您使用 close() 方法来确认连接确实被返回到了连接池而不是被彻底关闭了。在“finally{}”块中指定 close() 方法使得执行过程中发生的异常会被捕获到,并且该语句仍被执行 — 连接返回到连接池,这就防止了应用程序中“连接泄漏(connection leak)”的发生。

以下是构建一个 JDBC 连接的示例:

Connection con = null;
try { ds = (DataSource)myContext.lookup("<specify JDBC driver>");
  pooledCon = ds.getConnection("scott", "tiger");
// Processing Code goes here
} catch (Exception ignored) {
  // catch JNDI or JDBC exceptions here
} finally {
  if(pooledCon != null)
  pooledCon.close();
}



使用 PreparedStatement
人们认为 PreparedStatement 对象的效率比多个 Statement 对象更高,尤其是如果您必须多次执行同一条语句而差别仅在于参数不同时更是如此。PreparedStatement 允许您将 SQL 语句“编译”一次(尽管这种编译第一次要消耗较多的时间),然后将它保存在高速缓存中,从而实现有效的重用。同时它也提供了可读性更好的代码。

另一个额外的优势是由驱动程序完成的对用户传递给语句的字符串的自动转义。举例来说,这意味着当您试图将字符串“D'Marco”插入到一个基于字符的数据域(它可能是 VARCHAR, VARCHAR2, CHAR 等)中时,SQL 语句不会在遇到第一个撇号时就产生灾难性的失败。

使用 PreparedStatement 对象时的另一个良好习惯是调用对象自身的 close() 方法来“关闭对象”,这个方法将被用来运行 SQL 语句。这会关闭任何与正在执行的 SQL 语句相关联的游标,这样就能防止打开的游标把数据库弄得十分凌乱。

以下是一个创建 PreparedSatement 的示例:

PreparedStatement sqlstmt = dbCon.prepareStatement("select *
from table1 where field_1=?");
sqlstmt.setInt(1, 12);
ResultSet rs = sqlstmt.executeQuery();
// close the resultset statement to avoid hanging cursors in database
sqlstmt.close();
// processing of new statement
sqlstmt = dbCon.prepareStatement("select * from table2 where field_2 = ?");
// repeat creating the result set



恰当地利用事务
在更新动态数据库表和数据时常常会遗忘的一个方面,就是在向超过一个表示一个逻辑事务的表更新或插入数据时,这个事务应该反映到所有的表中,或者在碰到事务失败时,通过“回滚”该事务而在每一个表中都没有反映。

一些核心的 JDBC 包支持了四种事务隔离模式(transaction isolation mode),这些模式允许程序指定它们想事务表现出怎样的行为。大多数程序都至少支持两种模式:“读取提交(read committed)”(缺省值)和“可序列化的(serializable)”。当不可重复读取应该允许在多个查询之间由一个事务作出的修改对于另一个事务可见时,请使用“读取提交”;要使由另一个事务作出的修改在一个查询运行时成为可见的,请使用幻象读取(phantom read)。当您需要一个跨多个操作前后完全一致的数据库视图时,就应该使用更为严格的“可序列化的”设置。把连接的自动提交设置为“假”(autocommit = "false"),记住这一点是很有用的。

以下是构建一个连接并设置其各个属性参数的示例:

Connection con = null;
try {
dtsr = (DataSource <the JDBC driver you use>");
pConn = dtsr.getConnection("<specify login>", "<specify password>");
pConn.setAutoCommit(false); // transaction are not committed uponm execution

pConn.setTransactionIsolation(
Connection.TRANSACTION_SERIALIZABLE);
// pConn is pooled connection
pConn.commit();
} catch (Exception ignored) {
  try { pConnn.rollback(); } catch (SQLException esgl) {}
} finally {
  if(pConn != null) {
pConn.setAutoCommit(true); //reset autocommit
   pConn.close();
  }
}



您也可以利用一个可选的 JDBC 包 — JTA(Java Transaction API),它允许容易地和完全独立的事务服务器进行集成。

结束语
本提示的目的是为了帮助您使您的显示企业数据的移动应用程序能更可靠更有效地工作。但是,对于不正确的编码或部署,本提示于事无补。请始终确保您正在编写正确的代码并一而再、再而三地测试!



作者 Re:提示和技巧:JDBC 提示 [Re:palatum]
mabinde



发贴: 0
积分: 0
于 2003-01-04 14:40 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
up



flat modethreaded modego to previous topicgo to next topicgo to back
  已读帖子
  新的帖子
  被删除的帖子
Jump to the top of page

   Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent
Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1
客服电话 18559299278    客服信箱 714923@qq.com    客服QQ 714923