作者:feichangcai;feichangcai
原文:http://www.matrix.org.cn/resource/article/2006-11-19/Mustang+JDBC_c8c66f03-77c2-11db-bdce-bdc029e475a1.html
关键字:Mustang;JDBC
Java SE 6.0
Java SE 6.0版以兼容性、稳定性和品质作为设计目标。本版本中有不少值得关注的增强特性,特别是JMX、web services、脚本语言支持(采用Rhino脚本引擎JSR 223把JavaScript技术与Java源码进行集成)、数据库连接、支持annotations和安全部分。另外,在JDBC API中还有不少新的特性,包括RowId支持和新增的SQLException子类。
JDBC 4.0的特性
得益于Mustang中的Java SE 服务提供商机制,Java开发人员再也不必用类似Class.forName()的代码注册JDBC驱动来明确加载JDBC。当调用DriverManager.getConnection()方法时,DriverManager类将自动设置合适的驱动程序。该特性向后兼容,因此无需对现有的JDBC代码作任何改动。
通过对Java应用程序访问数据库代码的简化,使得JDBC 4.0有更好的开发体验。JDBC 4.0同时也提供了工具类来改进数据源和连接对象的管理,也改进了JDBC驱动加载和卸载机制。
有了JDBC 4.0传承自Java SE 5.0 (Tiger)版对元数据的支持功能,Java开发人员可用Annotations明确指明SQL查询。基于标注的SQL查询允许我们通过在Java代码中使用Annotation关键字正确指明SQL查询字符串。这样,我们不必查看JDBC代码和他所调用的数据库两份不同的文件。例如,用一个名为getActiveLoans()方法在贷款处理数据库中获取一个活跃贷款清单,你可以添加@Query(sql="SELECT * FROM LoanApplicationDetails WHERE LoanStatus = 'A'")标注来修饰该方法。
并且,最终版的Java SE 6开发包(JDK 6)以及其相应的执行期环境(JRE 6)会捆绑一个基于Apache Derby的数据库。这使得Java开发人员无需下载、安装和配置一款单独的数据库产品就能探究JDBC的新特性。
JDBC 4.0中增加的主要特性包括:
1. JDBC驱动类的自动加载
2. 连接管理的增强
3. 对RowId SQL类型的支持
4. SQL的DataSet实现使用了Annotations
5. SQL异常处理的增强
6. 对SQL XML的支持
另外,对BLOB/CLOB 的改进支持以及对国际字符集的支持也是JDBC 4.0的特性。这些特性将在随后章节中详细讨论。
JDBC驱动自动加载
在JDBC 4.0中,我们不必再使用Class.forName()方法明确加载JDBC驱动。当调用getConnection方法时,DriverManager会尝试从初始化时已经加载的JDBC驱动程序库中选择合适的驱动,以及他在当前应用的同一个类加载器中明确加载使用过的驱动。
DriverManager中的getConnection和getDrivers方法已作了改进,以支持Java SE 服务提供商机制(SPM)。根据SPM,所谓服务就是一组广为人知的接口和抽象类的集合,而服务提供商就是对某一服务的特定实现。SPM还指明了服务提供商的配置文件存放于META-INF/services目录下。JDBC 4.0的驱动程序库必须包含META-INF/services/java.sql.Driver文件。该文件包含对java.sql.Driver 实现的JDBC驱动文件名。例如,通过JDBC驱动连接Apache Derby数据库,META-INF/services/java.sql.Driver将含有以下路径:
org.apache.derby.jdbc.EmbeddedDriver
我们再来快速地看一下如何使用这一新特性加载一个JDBC驱动管理。以下显示的是我们用以加载JDBC驱动的典型范例代码。这里我们假设连接的是Apache Derby数据库,因为该数据库将在本文随后的范例应用中用到:
Class.forName("org.apache.derby.jdbc.EmbeddedDriver Connection conn =DriverManager.getConnection(jdbcUrl, jdbcUser, jdbcPassword);
但在JDBC 4.0中,我们不必写Class.forName()这一行,我们只需要调用getConnection()方法取得数据库连接。
请注意,仅在完全独立的模式下可使用该方法取得数据库的连接。如果你使用一些类似数据库连接池等技术管理连接,那么代码将有所不同。
连接管理
在JDBC 4.0之前,我们依靠JDBC URL来定义一个数据源连接。现在有了JDBC 4.0,我们只需为标准连接工厂机制提供一组参数,就能获取与任何数据源的连接。Connection和Statement接口增添的新方法为池环境中管理Statement对象提供了更好的连接状态跟踪机制和更大的灵活度。元数据工具(JSR-175)被用来管理活跃连接。我们还能获得元数据信息,如:活跃连接状态,并能指明XA事务的某一连接是标准式(Connection,在独立应用的情况下)、池式(PooledConnection)还是分布式(XAConnection)。该接口仅在诸如WebLogic、WebSphere和JBoss等Java EE应用服务器的事务管理中使用。
RowId支持
JDBC 4.0增加了RowID接口以支持ROWID数据类型,Oracle和DB2数据库支持该数据类型。在你需要把大量缺少唯一标识符字段的查询记录放入一个不允许重复对象的Collection容器(如Hashtable)的情况下,RowId很有用。我们可以用ResultSet的getRowId()方法获取RowId,用PreparedStatement的setRowId()方法在查询中使用RowId。
关于RowId对象需要记住的一件重要事项是,RowId值在数据源之间不可移植。当在PreparedStatement和ResultSet中单独使用set或update方法时,需要想到指明数据源。因此,RowId对象不应被不同的Connection和ResultSet对象共享。
DatabaseMetaData中的getRowIdLifetime()方法可被用来确定RowId对象的有效存活时间。该方法的可能返回值如表1所列:
RowId值 描述
ROWID_UNSUPPORTED Doesn't support ROWID data type.
ROWID_VALID_OTHER Lifetime of the RowID is dependent on database vendor implementation.
ROWID_VALID_TRANSACTION Lifetime of the RowID is within the current transaction as long as the row in the database table is not deleted.
ROWID_VALID_SESSION Lifetime of the RowID is the duration of the current session as long as the row in the database table is not deleted.
ROWID_VALID_FOREVER Lifetime of the RowID is unlimited as long as the row in the database table is not deleted.
基于标注的SQL查询
JDBC 4.0对标注(Java SE 5新增)作了进一步规范和补充,他允许开发人员不必再写大量代码就能达到联系SQL查询和Java类的目的。并且,通过使用Generics(JSR 014)和元数据(JSR 175) API,我们只要指明查询的输入和输出参数就能将SQL查询与Java对象进行关联。我们还可以将查询结果捆绑在Java类上以加快查询输出的处理。将查询对象置于Java对象之中,我们可以不必像往常一样写所有代码。在Java代码中指明SQL查询,经常用到两种标注:
Select标注
Select标注用于在Java类中指明一个选择查询,使get方法能从数据库表中取回数据。表2显示的是Select标注的不同属性及其作用:
变量 类型 描述
sql String SQL Select query string.
value String Same as sql attribute.
tableName String Name of the database table against which -----------------------------the sql will be invoked.
readOnly, connected, scrollable Boolean Flags used to indicate if the returned DataSet is read-only or updateable, is connected to the back-end database, and is scrollable when used in connected mode respectively.
allColumnsMapped Boolean Flag to indicate if the column names in the sql annotation element are mapped 1-to-1 with the fields in the DataSet.
这里有一个应用Select标注从贷款数据库中获取所有活跃贷款的例子:
interface LoanAppDetailsQuery extends BaseQuery { @Select("SELECT * FROM LoanDetais where LoanStatus = 'A'") DataSet<LoanApplication> getAllActiveLoans();}
Sql标注同样允许I/O参数(参数标记以一个问号后跟一个整型数据表示)。这里是一个参数化sql查询的例子:
interface LoanAppDetailsQuery extends BaseQuery { @Select(sql="SELECT * from LoanDetails where borrowerFirstName= ?1 and borrowerLastName= ?2") DataSet<LoanApplication> getLoanDetailsByBorrowerName(String borrFirstName, String borrLastName);}
Update标注
Update标注用于修饰Query接口方法以更新数据库表中的一条或多条记录。Update标注必须包含一个sql标注类型元素。这里是一个Update标注的例子:
interface LoanAppDetailsQuery extends BaseQuery { @Update(sql="update LoanDetails set LoanStatus = ?1 where loanId = ?2") boolean updateLoanStatus(String loanStatus, int loanId);}
SQL异常处理的增强特性
异常处理是Java编程的一个重要部分,特别是对后台关系数据库进行连接或查询时。SQLException是我们用以指出与数据库相关错误的类。JDBC 4.0在SQLException处理中有不少增强。为了在处理SQLException时获得更好的开发体验,JDBC 4.0版作了如下增强:
1. 新的SQLException子类
2. 对因果关系的支持
3. 对改进的for-each循环的支持
新的SQLException类
SQLException的新子类提供了一种方法,使Java开发人员能写出更方便改动的错误处理代码。JDBC 4.0介绍了两个新的SQLException型别:
• SQL non-transient exception
• SQL transient exception
Non-Transient Exception:除非修正引发SQLException异常的代码,否则该异常在再次尝试相同JDBC操作失败后被抛出。表3显示了JDBC 4.0新增的SQLNonTransientException异常子类(SQL 2003规范中定义了SQLState类的值):
Exception class SQLState value
SQLFeatureNotSupportedException 0A
SQLNonTransientConnectionException 08
SQLDataException 22
SQLIntegrityConstraintViolationException 23
SQLInvalidAuthorizationException 28
SQLSyntaxErrorException 42
Transient Exception:当先前执行失败的JDBC操作在没有任何应用级功能干涉的情况下可能成功执行时,该异常被抛出。继承自SQLTransientException的新异常如表4所列:
Exception class SQLState value
SQLTransientConnectionException 08
SQLTransactionRollbackException 40
SQLTimeoutException None
因果关系
SQLException类现在支持Java SE链式异常机制(又称因果工具),它使我们能在一个JDBC操作中处理多条SQLException异常(如果后台数据库支持多条异常特性)。这种情形发生在执行一条可能会抛出多条SQLException异常的语句时。
我们可以调用SQLException中的getNextException()方法在异常链中进行迭代。这里是一些处理getNextException()因果关系的范例代码:
catch(SQLException ex) { while(ex != null) { LOG.error("SQL State:" + ex.getSQLState()); LOG.error("Error Code:" + ex.getErrorCode()); LOG.error("Message:" + ex.getMessage()); Throwable t = ex.getCause(); while(t != null) { LOG.error("Cause:" + t); t = t.getCause(); } ex = ex.getNextException(); } }
增强的For-Each环
Java SE 5中,SQLException类通过实现Iterable接口,增加了for-each循环支持的特性。这个循环的轨迹将会包括SQLException和其异常成因。这里的代码片断展示了SQLException中增加的增强型for-each环特性。
catch(SQLException ex) { for(Throwable e : ex ) { LOG.error("Error occurred: " + e); } }
对国际字符集转换的支持
以下是JDBC类处理国际字符集的新增特性:
1. JDBC数据类型:新增NCHAR、NVARCHAR、LONGNVARCHAR和NCLOB数据类型。
2. PreparedStatement:新增setNString、setNCharacterStream和setNClob方法。
3. CallableStatement:新增getNClob、getNString和getNCharacterStream方法。
4. ResultSet:ResultSet接口新增updateNClob、updateNString和updateNCharacterStream方法。
对大对象(BLOBs and CLOBs)支持的改进
以下是JDBC 4.0处理LOBs的新增特性:
1. Connection:新增方法(createBlob()、createClob()和createNClob())以创建BLOB、CLOB和NCLOB对象新实例。
2. PreparedStatement:新增方法setBlob()、setClob()和setNClob()以使用InputStream对象插入BLOB对象,使用Reader对象插入CLOB和NCLOB对象。
3. LOBs:在Blob、Clob和NClob接口中新增方法(free())以释放这些对象所持有的资源。
现在,让我们来看一看java.sql和javax.jdbc包的新类,以及他们所提供的服务。
JDBC 4.0 API:新类
RowId (java.sql)
正如先前所介绍的,该接口是对数据库中SQL ROWID值的展示。ROWID是一种SQL内建的数据类型,用来标识数据库中的一行特定数据。ROWID经常用于从表中返回查询结果,而这些结果行往往缺少唯一ID字段。
getRowId和setRowId等CallableStatement、PreparedStatement和ResultSet接口的方法允许程序员访问SQL ROWID值。RowId接口还提供了一个方法(叫getBytes())把ROWID值作为一个byte型数组返回。DatabaseMetaData接口有一个名为getRowIdLifetime的新方法,用以确定某一RowId对象的存活时间。RowId的存活时间范围可以是如下三种类型:
1. 创建RowId的数据库事务持续时间
2. 创建RowId的会话持续时间
3. 数据库对应的记录还未被删除的持续时间
DataSet (java.sql)
DataSet接口提供了对执行SQL Query后所返回数据类型的安全检查。DataSet还可以运行在连接或非连接模式。在连接模式下,DataSet类似于ResultSet的功能;而在非连接模式下,他类似于CachedRowSet的功能。由于DataSet继承自List接口,因此我们能对查询返回的记录行进行迭代。
对已有的类,JDBC 4.0也新增了不少方法。比如,Connection新增了createSQLXML和createSQLXML方法,ResultSet新增了getRowId方法。
范例应用
本文所示的范例应用是一个贷款处理应用软件,他有一个贷款搜索页面,用户可以通过输入贷款ID提交查询表,以获取贷款详情。贷款搜索页面调用一个控制器对象,而该对象又调用一个DAO对象访问后台数据库,以取回贷款详情。这些详情包括贷款人、贷款数额、贷款截至日期等信息,并显示在贷款详情屏幕上。后台数据库中,我们有一个名为LoanApplicationDetails的表,来存储贷款软件的详情。
该范例应用的用例是通过指定贷款ID来获取贷款详情。当贷款已经登记并将抵押物与利息挂钩后,贷款详情就可以被获取。表5显示了贷款处理应用软件项目的详情。
Name Value
Project Name JdbcApp
Project Directory c:\dev\projects\JdbcApp
DB Directory c:\dev\dbservers\apache\derby
JDK Directory c:\dev\java\jdk_1.6.0
IDE Directory c:\dev\tools\eclipse
Database Apache Derby 10.1.2.1
JDK 6.0 (beta 2 release)
IDE Eclipse 3.1
Unit Testing JUnit 4
Build Ant 1.6.5
下表所列的是我们连接贷款详情Apache Derby数据库所需的JDBC参数。这些参数存放于一个名为derby.properties的文本文件中,并置于项目的etc/jdbc目录下(见表6)。
Name Value
JDBC Driver File LoanApp\META-INF\services\java.sql.driver
Driver org.apache.derby.ClientDriver
URL jdbc:derby:derbyDB
User Id user1
Password user1
请注意:Apache Derby数据库提供了两种JDBC驱动:嵌入式驱动(org.apache.derby.jdbc.EmbeddedDriver)和客户端/服务器驱动(org.apache.derby.jdbc.ClientDriver)。我在范例应用中使用客户端/服务器版驱动。
以下是使用ij工具来启动Derby数据库服务器并创建新数据库的命令。
要启动Derby网络服务器,需开启一个命令行窗口,并运行如下命令(请根据你本机的环境改写DERBY_INSTALL和JAVA_HOME环境变量)。
set DERBY_INSTALL=C:\dev\dbservers\db-derby-10.1.2.1-binset JAVA_HOME=C:\dev\java\jdk1.6.0set DERBY_INSTALL=C:\dev\dbservers\db-derby-10.1.3.1-binset CLASSPATH=%CLASSPATH%;%DERBY_INSTALL%\lib\derby.jar; %DERBY_INSTALL%\lib\derbytools.jar; %DERBY_INSTALL%\lib\derbynet.jar;cd %DERBY_INSTALL%\frameworks\NetworkServer\binstartNetworkServer.bat
要连接数据库服务器并创建测试数据库,需开启另一个命令行窗口并运行以下命令。请确保DERBY_INSTALL和JAVA_HOME环境变量符合你本机的环境。
set JAVA_HOME=C:\dev\java\jdk1.6.0set DERBY_INSTALL=C:\dev\dbservers\db-derby-10.1.3.1-binset CLASSPATH=%DERBY_INSTALL%\lib\derbyclient.jar; %DERBY_INSTALL%\lib\derbytools.jar; .%JAVA_HOME%\bin\java org.apache.derby.tools.ijconnect 'jdbc:derby://localhost:1527/LoanDB; create=true';
测试
要编译Java源代码,classpath需包括derby.jar和junit4.jar文件,这两个文件在项目的lib目录下。Classpath还需包括etc、etc/jdbc和etc/log4j目录,这样应用程序才能访问JDBC属性文件和Log4J配置文件。我创建了一个Ant构建脚本(在JdbcApp/build目录下)来自动完成编译和打包Java源代码的工作。
用于测试贷款详情数据库访问对象的测试类名为LoanAppDetailsDAOTest。我们传入贷款ID和贷款人参数就可以获取贷款详情。
以下部分显示了JDBC 4.0中自动加载JDBC驱动和基于标注的SQL查询特性的代码范例。
JDBC驱动的自动加载
BaseDAO抽象类有一个名为getConnection的方法用以获得一个数据库连接。以下代码片断显示了该方法(注意,我们不必注册JDBC驱动)。只要java.sql.Driver文件中有合适的驱动程序类名(org.apache.derby.jdbc.ClientDriver),JDBC驱动将被自动加载。
protected Connection getConnection() throws DAOException { // Load JDBC properties first if (jdbcUrl == null || jdbcUser == null || jdbcPassword == null) { loadJdbcProperties(); } // Get Connection Connection conn = null; try { conn = DriverManager.getConnection(jdbcUrl, jdbcUser, jdbcPassword); } catch (SQLException sqle) { throw new DAOException("Error in getting a DB connection.", sqle); } return conn; } }
SQL标注
LoanAppDetailsQuery接口有标注了的SQL查询,用以获取活跃贷款清单(criteria is loanstatus="A")和某贷款人的贷款详情(在一个贷款人有多笔贷款的情况下)。在上文中,我们已经了解过了这些SQL标注。这里的范例代码显示了我们如何使用标注来调用已定义的SQL查询。
结论
JDBC 4.0在SQL方面为开发者提供了更好的开发体验。JDBC 4.0的另一个目标是为API增加更丰富的工具以提供企业级JDBC特性管理JDBC资源。并且,JDBC 4.0 API还提供了JDBC驱动的移植方式,使其符合J2EE连接器架构(JCA)规范。这为JDBC厂商提供了向JDBC连接器迁移的能力。在面向企业服务的架构(SPA)中使用JDBC数据源,该移植方式很重要。在SOA中,JDBC数据源可被部署在另一个企业服务总线(ESB)架构内,而不需要为JDBC数据源另写一份ESB实现代码。
发表评论
-
jdbc 最佳实践
2011-03-08 09:05 885做个记录 http://www.precisejava.co ... -
weblogic8.1中的jstl使用问题
2011-03-02 13:36 1396项目中使用的是weblogic8.1.5,js ... -
maven 小结
2011-01-29 15:09 1384一、Maven是什么? ... -
ThreadLocal模式总结
2010-11-28 18:18 2448ThreadLoca ... -
DatabaseMetaData的使用
2009-12-08 16:26 788关于它的使用,转两篇文章。。。。 http://hi.baid ...
相关推荐
标题“sqljdbc4.0”指的是SQL Server JDBC驱动的一个特定版本,主要用于Java应用程序与Microsoft SQL Server数据库之间的连接。SQL JDBC是微软提供的一个开源驱动,它实现了Java Database Connectivity (JDBC) API,...
- **JDBC 4.0规范兼容**:遵循Java SE 6引入的JDBC 4.0规范,提供了诸如Automatic Registering of JDBC Drivers、Java Persistence API (JPA) 支持等新特性。 在实际开发中,使用`sqljdbc_4.0`压缩包中的JDBC驱动,...
2. **JDBC 4.0新特性**: - 自动注册驱动:使用`Class.forName()`方法不再必要,因为JDBC 4.0驱动会自动注册到Java虚拟机。 - 高级连接池:提供了更高级别的连接池管理,增强了性能和资源利用率。 - 新的`...
然而,由于某些原因,微软不再支持从Maven中央仓库直接下载sqljdbc4.0.jar,这给开发者带来了不便。因此,为了方便开发者获取和使用,我们提供了这个压缩包文件。 SQL JDBC 4.0驱动是SQL Server JDBC驱动的第四代...
在本文中,我们将详细探讨SQLJDBC4.0驱动的关键特性和使用方法。 首先,JDBC是一种Java API,允许Java程序员使用标准的Java语言来连接和操作各种关系型数据库。SQLJDBC4.0是微软提供的类型4 JDBC驱动,它是一个纯...
《JDBC 4.0规范》是Java数据库连接(Java ...通过改进异常处理、增强类型映射、优化性能以及提供更为灵活的资源管理机制,JDBC 4.0为Java应用程序与数据库的交互开辟了新的路径,极大地促进了Java生态系统的繁荣发展。
- `sqljdbc4.0.jar` 驱动可能不支持最新的SQL Server特性或版本,因此在新项目中应考虑使用更新的驱动版本,如`sqljdbc42.jar`或`sqljdbc43.jar`。 总之,`sqljdbc4.0.jar` 是一个关键的工具,它使得Java开发者能够...
**JDBC4.0 API一览表** Java Database Connectivity (JDBC) 是Java编程语言中用于规范应用程序如何访问数据库的标准接口。JDBC4.0是Oracle公司在JDBC3.0基础上进行的一次重大更新,旨在提高数据库操作的效率、稳定...
这个"spring-jdbc4.0.jar"包是针对Spring框架4.0版本的JDBC支持组件,包含了一系列接口和类,用于简化数据库的访问过程。 首先,Spring JDBC的核心类`JdbcTemplate`是其主要功能的入口点。这个模板类提供了大量的...
### JDBC 4.0 规范详解 #### 一、概述 JDBC(Java Database Connectivity)是 Java 平台提供的一套标准接口,...对于那些需要与数据库交互的 Java 应用来说,了解并掌握 JDBC 4.0 的新特性和最佳实践是非常必要的。
**JDBC4.0与SQL Server连接包** Java Database Connectivity...通过这个“jdbc4.0 sql server连接包”,Java开发者能够轻松地与SQL Server 2008进行交互,利用JDBC4.0的新特性和优势,实现高效、可靠的数据库应用。
JDBC 连接方法及驱动的使用\SQL SERVER 2008 JDBC\eeclipse jdk1.6 下用sqljdbc4.0驱动连接数据库.java
- 支持JDBC 4.0规范:SQLJDBC 4.0遵循了JDBC 4.0的标准,引入了新的API和改进,如自动注册驱动、异步操作支持等。 - 改进的性能:通过优化网络通信和查询处理,提高了数据读取和写入的速度。 - 支持Unicode 5.1:...
在4.0版本中,开发者可以利用新的API特性,比如自动注册驱动、更强大的异常处理能力以及对Java 7的全面支持。 在压缩包文件`sqljdbc4-3.0.jar`和`sqljdbc4-4.0.jar`中,分别包含了对应版本的驱动程序类库。将这些...
2. 版本信息:4.0版代表了驱动的成熟度和兼容性,通常包含了一些新特性、性能优化以及对旧版本问题的修复。这个版本可能支持SQL Server 2005及更高版本,并提供对JDBC 4.0规范的完全支持。 3. 驱动类型:SQLJDBC_...
这些新特性包括: 1. **自动发现服务(Automatic Service Discovery)**:允许驱动程序自动发现数据库服务器,简化了连接配置。 2. **统一的异常处理(Unified Exception Handling)**:通过SQLException的新的...
5. 使用方法:在Java项目中,要使用SQLJDBC驱动,首先需要将对应的JAR文件(如sqljdbc4.0-4.2.zip中的文件)添加到项目的类路径中。然后,通过`Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver")`加载...
这个版本的驱动引入了多项新特性和性能优化,以提高Java应用与SQL Server之间的交互效率。 JDBC 4.0规范引入了一些新的接口和特性,例如Automatic Java Persistence (JPA)、Java EE 6的支持以及改进的连接池管理。...
SQL server的jdbc驱动,版本4.0.0,适用于大多sqlserver数据库。