- 浏览: 424931 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
iwwenbo:
别逗好不好
Popup.js 弹出窗口 -
bugnuke:
尼玛 跑不了。。。
Popup.js 弹出窗口 -
tangzhifei:
创建Subversion授权文件放哪目录下?前面我的都对了,到 ...
Trac系列(8):windows下Apache+SVN+Trac安装及配置(一) -
zoutuo1986:
正在安装,确实很慢,一定要选择网速快的时候安装,
eclipse 插件springide安装 -
johnsonyang:
this.jmsTemplate.send(
...
spring,weblogic配置jms
2006 年底,Sun 公司发布了 Java Standard Edition 6(Java SE 6)的最终正式版,代号 Mustang(野马)。跟 Tiger(Java SE 5)相比,Mustang 在性能方面有了不错的提升。与 Tiger 在 API 库方面的大幅度加强相比,虽然 Mustang 在 API 库方面的新特性显得不太多,但是也提供了许多实用和方便的功能:在脚本,WebService,XML,编译器 API,数据库,JMX,网络和 Instrumentation 方面都有不错的新特性和功能加强。 本系列 文章主要介绍 Java SE 6 在 API 库方面的部分新特性,通过一些例子和讲解,帮助开发者在编程实践当中更好的运用 Java SE 6,提高开发效率。
本文是系列文章的第 5 篇,介绍了 Java SE 6 在数据库编程方面的新特性。
Java DB:Java 6 里的数据库
新安装了 JDK 6 的程序员们也许会发现,除了传统的 bin、jre 等目录,JDK 6 新增了一个名为 db 的目录。这便是 Java 6 的新成员:Java DB。这是一个纯 Java 实现、开源的数据库管理系统(DBMS),源于 Apache 软件基金会(ASF)名下的项目 Derby。它只有 2MB 大小,对比动辄上 G 的数据库来说可谓袖珍。但这并不妨碍 Derby 功能齐备,支持几乎大部分的数据库应用所需要的特性。更难能可贵的是,依托于 ASF 强大的社区力量,Derby 得到了包括 IBM 和 Sun 等大公司以及全世界优秀程序员们的支持。这也难怪 Sun 公司会选择其 10.2.2 版本纳入到 JDK 6 中,作为内嵌的数据库。这就好像为 JDK 注入了一股全新的活力:Java 程序员不再需要耗费大量精力安装和配置数据库,就能进行安全 、易用、标准、并且免费的数据库编程。在这一章中,我们将初窥 Java DB 的世界,来探究如何使用它编写出功能丰富的程序。
Hello, Java DB:内嵌模式的Derby
既然有了内嵌(embedded)的数据库,就让我们从一个简单的范例(代码在 清单 1 中列出)开始,试着使用它吧。这个程序做了大多数数据库应用都可能会做的操作:在 DBMS 中创建了一个名为 helloDB 的数据库;创建了一张数据表,取名为 hellotable;向表内插入了两条数据;然后,查询数据并将结果打印在控制台上;最后,删除表和数据库,释放资源。
清单 1. HelloJavaDB 的代码
public class HelloJavaDB { public static void main(String[] args) { try { // load the driver Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance(); System.out.println("Load the embedded driver"); Connection conn = null; Properties props = new Properties(); props.put("user", "user1"); props.put("password", "user1"); //create and connect the database named helloDB conn=DriverManager.getConnection("jdbc:derby:helloDB;create=true", props); System.out.println("create and connect to helloDB"); conn.setAutoCommit(false); // create a table and insert two records Statement s = conn.createStatement(); s.execute("create table hellotable(name varchar(40), score int)"); System.out.println("Created table hellotable"); s.execute("insert into hellotable values('Ruth Cao', 86)"); s.execute("insert into hellotable values ('Flora Shi', 92)"); // list the two records ResultSet rs = s.executeQuery( "SELECT name, score FROM hellotable ORDER BY score"); System.out.println("name\t\tscore"); while(rs.next()) { StringBuilder builder = new StringBuilder(rs.getString(1)); builder.append("\t"); builder.append(rs.getInt(2)); System.out.println(builder.toString()); } // delete the table s.execute("drop table hellotable"); System.out.println("Dropped table hellotable"); rs.close(); s.close(); System.out.println("Closed result set and statement"); conn.commit(); conn.close(); System.out.println("Committed transaction and closed connection"); try { // perform a clean shutdown DriverManager.getConnection("jdbc:derby:;shutdown=true"); } catch (SQLException se) { System.out.println("Database shut down normally"); } } catch (Throwable e) { // handle the exception } System.out.println("SimpleApp finished"); } } 随后,我们在命令行(本例为 Windows 平台,当然,其它系统下稍作改动即可)下键入以下命令:
程序将会按照我们预想的那样执行,图 1 是执行结果的一部分截屏:
上述的程序和以往没什么区别。不同的是我们不需要再为 DBMS 的配置而劳神,因为 Derby 已经自动地在当前目录下新建了一个名为 helloDB 的目录,来物理地存储 数据和日志。需要做的只是注意命名问题:在内嵌模式下驱动的名字应为 org.apache.derby.jdbc.EmbeddedDriver;创建一个新数据库时需要在协议 后加入 create=true。另外,关闭所有数据库以及 Derby 的引擎可以使用以下代码:
如果只想关闭一个数据库,那么则可以调用:
这样,使用嵌入模式的 Derby 维护和管理数据库的成本接近于 0。这对于希望专心写代码的人来说不失为一个好消息。然而有人不禁要问:既然有了内嵌模式,为什么大多数的 DBMS 都没有采取这样的模式呢?不妨做一个小实验。当我们同时在两个命令行窗口下运行 HelloJavaDB 程序。结果一个的结果与刚才一致,而另一个却出现了错误,如 图 2 所示。
错误的原因其实很简单:在使用内嵌模式时,Derby 本身并不会在一个独立的进程中,而是和应用程序一起在同一个 Java 虚拟机(JVM)里运行。因此,Derby 如同应用所使用的其它 jar 文件一样变成了应用的一部分。这就不难理解为什么在 classpath 中加入 derby 的 jar 文件,我们的示例程序就能够顺利运行了。这也说明了只有一个 JVM 能够启动数据库:而两个跑在不同 JVM 实例里的应用自然就不能够访问同一个数据库了。 鉴于上述的局限性,和来自不同 JVM 的多个连接想访问一个数据库的需求,下一节将介绍 Derby 的另一种模式:网络服务器 (Network Server)。 网络服务器 模式 如上所述,网络服务器模式是一种更为传统的客户端/服务器模式。我们需要启动一个 Derby 的网络服务器用于处理客户端的请求,不论这些请求是来自同一个 JVM 实例,还是来自于网络上的另一台机器。同时,客户端使用 DRDA(Distributed Relational Database Architecture)协议 连接到服务器端。这是一个由 The Open Group 倡导的数据库交互标准。图 3 说明了该模式的大体结构。 由于 Derby 的开发者们努力使得网络服务器模式与内嵌模式之间的差异变小,使得我们只需简单地修改 清单 1 中的程序就可以实现。如 清单 5所示,我们在 HelloJavaDB 中增添了一个新的函数和一些字符串变量。不难看出,新的代码只是将一些在 上一节中特别指出的字符串进行了更改:驱动类为 org.apache.derby.jdbc.ClientDriver,而连接数据库的协议 则 变成了 jdbc:derby://localhost:1527/。这是一个类似 URL 的字符串,而事实上,Derby 网络的客户端的连接格式为:jdbc:derby://server[:port] /databaseName[;attributeKey=value]。在这个例子中,我们使用了最简单的本地机器作为服务器,而端口则是 Derby 默认的 1527 端口。
当然,仅仅有客户端是不够的,我们还需要启动网络服务器。Derby 中控制网络服务器的类是 org.apache.derby.drda.Net workServerControl,因此键入以下命令即可。如果想了解 NetworkServerControl 更多的选项,只要把 start 参数去掉就可以看到帮助信息了。关于网络服务器端的实现,都被 Derby 包含在 derbynet.jar 里。 清单 6. 启动网络服务器
相对应的,网络客户端的实现被包含在 derbyclient.jar 中。所以,只需要在 classpath 中加入该 jar 文件,修改后的客户端就可以顺利地读取数据了。再一次尝试着使用两个命令行窗口去连接数据库,就能够得到正确的结果了。如果不再需要服务器,那么使用 NetworkServerControl 的 shutdown 参数就能够关闭服务器。 更多 至此,文章介绍了 Java SE 6 中的新成员:Java DB(Derby),也介绍了如何在内嵌模式以及网络服务器模式下使用 Java DB。当然这只是浅尝辄止,更多高级的选项还需要在 Sun 和 Derby 的文档中寻找。在这一章的最后,我们将简单介绍几个 Java DB 的小工具来加快开发速度。它们都位于 org.apache.derby.tools 包内,在开发过程中需要获取信息或者测试 可以用到。
JDBC 4.0:新功能,新 API 如果说上一章介绍了 Java 6 中的一个新成员,它本来就存在,但是没有被加入进 JDK。那么这一章,我们将关注在 JDBC 4.0 中又增加了哪些新功能以及与之相对应的新 API。 自动加载驱动 在 JDBC 4.0 之前,编写 JDBC 程序都需要加上以下这句有点丑陋的代码:
Java.sql.DriverManager 的内部实现机制决定了这样代码的出现。只有先通过 Class.forName 找到特定驱动的 class 文件,DriverManager.getConnection 方法才能顺利地获得 Java 应用和数据库的连接。这样的代码为编写程序增加了不必要的负担,JDK 的开发者也意识到了这一点。从 Java 6 开始,应用程序不再需要显式地加载驱动程序了,DriverManager 开始能够自动地承担这项任务。作为试验,我们可以将 清单 1 中的相关代码删除,重新编译后在 JRE 6.0 下运行,结果和原先的程序一样。 好奇的读者也许会问,DriverManager 为什么能够做到自动加载呢?这就要归功于一种被称为 Service Provider 的新机制。熟悉 Java 安全 编 程的程序员可能对其已经是司空见惯,而它现在又出现在 JDBC 模块中。JDBC 4.0 的规范规定,所有 JDBC 4.0 的驱动 jar 文件必须包含一个 java.sql.Driver,它位于 jar 文件的 META-INF/services 目录下。这个文件里每一行便描述了一个对应的驱动类。其实,编写这个文件的方式和编写一个只有关键字(key)而没有值(value)的 properties 文件类似。同样地,‘#’之后的文字被认为是注释。有了这样的描述,DriverManager 就可以从当前在 CLASSPATH 中的驱动文件中找到,它应该去加载哪些类。而如果我们在 CLASSPATH 里没有任何 JDBC 4.0 的驱动文件的情况下,调用 清单 8 中的代码会输出一个 sun.jdbc.odbc.JdbcOdbcDriver 类型的对象。而仔细浏览 JDK 6 的目录,这个类型正是在 %JAVA_HOME%/jre/lib/resources.jar 的 META-INF/services 目录下的 java.sql.Driver 文件中描述的。也就是说,这是 JDK 中默认的驱动。而如果开发人员想使得自己的驱动也能够被 DriverManager 找到,只需要将对应的 jar 文件加入到 CLASSPATH 中就可以了。当然,对于那些 JDBC 4.0 之前的驱动文件,我们还是只能显式地去加载了。
RowId 熟悉 DB2、Oracle 等大型 DBMS 的人一定不会对 ROWID 这个概念陌生:它是数据表中一个“隐藏”的列,是每一行独一无二的标识,表明这一行的物理或者逻辑位置。由于 ROWID 类型的广泛使用,Java SE 6 中新增了 java.sql.RowId 的数据类型,允许 JDBC 程序能够访问 SQL 中的 ROWID 类型。诚然,不是所有的 DBMS 都支持 ROWID 类型。即使支持,不同的 ROWID 也会有不同的生命周期。因此使用 DatabaseMetaData.getRowIdLifetime 来判断类型的生命周期不失为一项良好的实践经验。我们在 清单 1 的程序获得连接之后增加以下代码,便可以了解 ROWID 类型的支持情况。 清单 9. 了解 ROWID 类型的支持情况
Java SE 6 的 API 规范中,java.sql.RowIdLifetime 规定了 5 种不同的生命周期:ROWID_UNSUPPORTED、ROWID_VALID_FOREVER、ROWID_VALID_OTHER、 ROWID_VALID_SESSION 和 ROWID_VALID_TRANSACTION。从字面上不难理解它们表示了不支持 ROWID、ROWID 永远有效等等。具体的信息,还可以参看相关的 JavaDoc。读者可以尝试着连接 Derby 进行试验,会发现运行结果是 ROWID_UNSUPPORTED ,即 Derby 并不支持 ROWID。 既然提供了新的数据类型,那么一些相应的获取、更新数据表内容的新 API 也在 Java 6 中被添加进来。和其它已有的类型一样,在得到 ResultSet 或者 CallableStatement 之后,调用 get/set/update 方法得到/设置/更新 RowId 对象,示例的代码如 清单 10 所示。
鉴于不同 DBMS 的不同实现,RowID 对象通常在不同的数据源(datasource)之间并不是可移植的。因此 JDBC 4.0 的 API 规范并不建议从连接 A 取出一个 RowID 对象,将它用在连接 B 中,以避免不同系统的差异而带来的难以解释的错误。而至于像 Derby 这样不支持 RowId 的 DBMS,程序将直接在 setRowId 方法处抛出 SQLFeatureNotSupportedException。 SQLXML SQL: 2003 标准引入了 SQL/XML,作为 SQL 标准的扩展。SQL/XML 定义了 SQL 语言怎样和 XML 交互:如何创建 XML 数据;如何在 SQL 语句中嵌入 XQuery 表达式等等。作为 JDBC 4.0 的一部分,Java 6 增加了 java.sql.SQLXML 的类型。JDBC 应用程序可以利用该类型初始化、读取、存储 XML 数据。java.sql.Connection.createSQLXML 方法就可以创建一个空白的 SQLXML 对象。当获得这个对象之后,便可以利用 setString、setBinaryStream、setCharacterStream 或者 setResult 等方法来初始化所表示的 XML 数据。以 setCharacterStream 为例,清单 11 表示了一个 SQLXML 对象如何获取 java.io.Writer 对象,从外部的 XML 文件中逐行读取内容,从而完成初始化。
由于 SQLXML 对象有可能与各种外部的资源有联系,并且在一个事务中一直持有这些资源。为了防止应用程序耗尽资源,Java 6 提供了 free 方法来释放其资源。类似的设计在 java.sql.Array、Clob 中都有出现。 至于如何使用 SQLXML 与数据库进行交互,其方法与其它的类型都十分相似。可以参照 RowId 一节 中的例子在 Java SE 6 的 API 规范中找到 SQLXML 中对应的 get/set/update 方法构建类似的程序,此处不再赘述。 SQLExcpetion 的增强 在 Java SE 6 之前,有关 JDBC 的异常类型不超过 10 个。这似乎已经不足以描述日渐复杂的数据库异常情况。因此,Java SE 6 的设计人员对以 java.sql.SQLException 为根的异常体系作了大幅度的改进。首先,SQLException 新实现了 Iterable<Throwable> 接口。清单 12 实现了 清单 1 程序的异常处理机制。这样简洁地遍历了每一个 SQLException 和它潜在的原因(cause)。
此外,图 4 表示了全部的 SQLException 异常体系。除去原有的 SQLException 的子类,Java 6 中新增的异常类被分为 3 种:SQLReoverableException、SQLNonTransientException、SQLTransientException。 在 SQLNonTransientException 和 SQLTransientException 之下还有若干子类,详细地区分了 JDBC 程序中可能出现的各种错误情况。大多数子类都会有对应的标准 SQLState 值,很好地将 SQL 标准和 Java 6 类库结合在一起。
在众多的异常类中,比较常见的有 SQLFeatureNotSupportedException,用来表示 JDBC 驱动不支持某项 JDBC 的特性。例如在 Derby 下运行 清单 10 中的程序,就可以发现 Derby 的驱动并不支持 RowId 的特性。另外值得一提的是,SQLClientInfoException 直接继承自 SQLException,表示当一些客户端的属性不能被设置在一个数据库连接时所发生的异常。 小结:更多新特性与展望 在本文中,我们已经向读者介绍了 Java SE 6 中 JDBC 最重要的一些新特性:它们包括嵌在 JDK 中的 Java DB (Derby)和 JDBC 4.0 的一部分。当然,还有很多本文还没有覆盖到的新特性。比如增加了对 SQL 语言中 NCHAR、NVARCHAR、LONGNVARCHAR 和 NCLOB 类型的支持;在数据库连接池的环境下为管理 Statement 对象提供更多灵活、便利的方法等。 此外,在 Java SE 6 的 beta 版中,曾经将 Annotation Query 的特性包含进来。这项特性定义了一系列 Query 和 DataSet 接口,程序员可以通过撰写一些 Annotation 来自定义查询并获得定制的数据集结果。但是,由于这一特性的参考实现最终不能满足 JDK 的质量需求,Sun 公司忍痛割爱,取消了在 Java SE 6 中发布其的计划。我们有理由相信,在以后的 JDK 版本中,这一特性以及更多新的功能将被包含进来,利用 Java 语言构建数据库的应用也会变得更为自然、顺畅。 |
发表评论
-
Java SE 6 Web Service 之旅
2009-10-11 16:17 1835在过去的几个月里,Sun ... -
用Java动态代理实现AOP
2009-10-10 13:38 997目前整个开发社区对AOP(Aspect Oriented Pr ... -
泛型DAO类设计模式
2009-10-10 11:56 951Generic Data Access Objects ... -
理解ThreadLocal
2009-07-27 22:29 857ThreadLocal是什么 早在JDK ... -
JSON taglib学习笔记
2008-11-04 10:11 1366JSON-taglib 是 JSP 2.0 标签库,用于 ... -
页面生成打开excel(运用poi)
2008-10-29 09:45 1197把excel作为流在页面输出 publ ... -
J2EE使用iText将数据保存为PDF文档
2008-09-18 21:36 1215在B/S结构的项目中,经 ... -
java操作Excel(Jakarta_POI)
2008-09-09 17:22 4012微软在桌面系统上的成 ... -
优化Java中的正则表达式
2008-09-09 14:14 1773如果你花费了数小时和正则表达式做斗争,只是为了让它完成它几秒内 ... -
Java对象池技术的原理及其实现
2008-09-09 09:24 1109Java对象的生命周期分析 Java对象的生命周期大致包括 ... -
jakarta commons logging 的使用方法(续一)
2008-09-08 11:36 856常用log4j配置,一般可以采用两种方式,.propertie ... -
jakarta commons logging 的使用方法(续)
2008-09-08 11:28 1907JCL(Jakarta Commons Logging)和lo ... -
在 Web 应用中增加用户跟踪功能
2008-09-08 11:02 1246随着 Web 应用的复杂化 ... -
在Java应用程序中访问USB设备
2008-09-08 10:48 1189Java 平台一直都以其平台无关性自豪。虽然这种无关性 ... -
正则表达式
2008-09-05 17:29 1195Java代码 检测时间 ([0-1]?[0-9]|2[ ... -
汉字验证码
2008-09-05 09:38 1521Java代码 package com.toy; ... -
java数字签名
2008-09-05 09:30 2130... -
jakarta commons logging 的使用方法
2008-09-05 09:30 1613日志(Logging)使得我们能够调试和跟踪应用程序任意时刻的 ...
相关推荐
可插拔注解是Java SE 6引入的一项新特性,它允许开发者定义自定义注解处理器来生成代码或其他元数据,这极大地提高了代码的可维护性和可扩展性。 #### 8. 桌面部署 为了提高桌面应用程序的部署体验,Java SE 6提供...
2. **db2jcc4.jar**:此驱动适用于Java SE 7及更高版本,它实现了JDBC 4.1和4.2规范,提供了更多新特性和改进,如更好的异常处理和新的时间日期类型支持。如果你的应用环境运行在Java 7或更新的版本上,应该优先考虑...
它支持JDBC 4.0和4.1规范,适用于Java SE 6及以上版本。 2. **db2jcc.jar**:这个文件可能是较旧版本的DB2 JDBC驱动,同样为Type 4驱动,但可能不包含最新特性或兼容性更新。在使用时,通常推荐使用最新版本的驱动...
6. **Java DB和JDBC 4.0**:Java 6内置了一个轻量级数据库引擎——Java DB(Apache Derby),提供了关系型数据库管理系统的功能。同时,JDBC 4.0引入了新的API,增强了连接池管理、自动关闭资源和异常处理,使得...
JDBC 4.0驱动是为Java SE 6及以上版本设计的,提供了更好的性能和功能。 4. SQL Server 2000 JDBC驱动: 尽管SQL Server 2000相对较老,但它仍然有可用的JDBC驱动,主要为JDBC 2.0标准。这些驱动让Java开发者能够...
1. **gsjdbc4.jar**: 这个jar文件可能对应于JDBC 4.0规范,它支持Java SE 6及更高版本。它包含了与高斯数据库通信的Driver类,例如`com.gauss.jdbc.Driver`,以及相关的JDBC接口实现。使用这个驱动时,你需要在代码...
它实现了JDBC 4.0规范,适用于Java SE 6及以上版本。要使用这个驱动,你需要将其添加到项目的类路径中。 4. **连接DB2**:在Java代码中,你可以通过以下步骤连接到DB2: - 加载驱动:`Class.forName(...
例如,它可能包含了对Java SE 6及更高版本的支持,包括改进的连接池管理和新的数据库元数据查询等特性。 使用这些驱动,开发者需要在Java项目中添加对应的jar文件,并配置数据库连接参数,如URL、用户名和密码。...
"4"可能代表JDBC 4.0或更高版本的兼容性,这意味着它支持Java SE 6及更高版本的JDBC规范。使用这个JAR文件,开发者可以利用更现代的Java和JDBC功能来与DB2数据库交互。 在实际开发中,将这些JAR文件添加到项目的类...
Derby数据库支持JDBC 4.0规范,这意味着开发者可以利用JDBC的新特性和属性来更高效地访问和管理数据。JDBC 4.0引入了许多改进,包括自动加载驱动、新的SQL异常处理、以及增强的连接池管理,提升了数据库操作的便捷性...
JDBC4是JDBC的一个版本,它在JDBC 4.0规范中定义,主要为Java SE 6及更高版本提供服务。 描述中提到的"jdbc 连接数据的jar包有需要的可以下载一下,里面包含怎么加载驱动的代码",意味着这个压缩包不仅提供了JDBC...
它由Java SE(标准版)的Java SQL API提供,允许Java应用程序通过一套统一的API来连接和操作不同的数据库系统,包括Oracle、Sybase、MySQL、DB2、SQL Server、Sybase、Informix和PostgreSQL等。以下将详细介绍JDBC...
1.2.3 J2SE 5.0新特性实践 26 1.3 小结 35 第2章 对象无处不在——面向对象的基本概念 37 2.1 讲解 38 2.1.1 什么是面向对象 38 2.1.2 面向对象的基本概念 38 2.1.3 Java对面向对象的支持 41 2.2 练习 42 ...
1.2.3 J2SE 5.0新特性实践 26 1.3 小结 35 第2章 对象无处不在——面向对象的基本概念 37 2.1 讲解 38 2.1.1 什么是面向对象 38 2.1.2 面向对象的基本概念 38 2.1.3 Java对面向对象的支持 41 2.2 练习 42 ...
JavaDB(也被称为Derby)是Sun Microsystems(现为Oracle公司)开发的一个轻量级、开源的关系型数据库,它是Java平台标准版(Java SE)的一部分。JavaDB提供了自己的JDBC驱动,使得开发者能够轻松地在Java应用程序中...
1.2.3 J2SE 5.0新特性实践 26 1.3 小结 35 第2章 对象无处不在——面向对象的基本概念 37 2.1 讲解 38 2.1.1 什么是面向对象 38 2.1.2 面向对象的基本概念 38 2.1.3 Java对面向对象的支持 41 2.2 练习 42 ...
版本14指的是JDBC 4.0规范(对应于Java SE 6),而10.2.0.1.0是Oracle数据库的特定版本。通过这个驱动,开发者可以使用Java语言执行Oracle SQL和PL/SQL语句,进行数据操作和管理。 在Java项目中,使用这些驱动通常...
在描述中提到,“sqljdbc4.jar”是用于连接SQL2008数据库的驱动程序,这表明它支持JDBC 4.0规范,这是Java SE 6引入的标准。这个版本的驱动程序提供了更高效、更稳定以及更安全的连接方式,同时增加了对新特性的支持...