扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
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中增加的主要特性包括:
另外,对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标注用于修饰Query接口方法以更新数据库表中的一条或多条记录。Update标注必须包含一个sql标注类型元素。这里是一个Update标注的例子:
interface LoanAppDetailsQuery extends BaseQuery { |
SQL异常处理的增强特性
异常处理是Java编程的一个重要部分,特别是对后台关系数据库进行连接或查询时。SQLException是我们用以指出与数据库相关错误的类。JDBC 4.0在SQLException处理中有不少增强。为了在处理SQLException时获得更好的开发体验,JDBC 4.0版作了如下增强:
新的SQLException类
SQLException的新子类提供了一种方法,使Java开发人员能写出更方便改动的错误处理代码。JDBC 4.0介绍了两个新的SQLException型别:
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者