科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道Java SE 6中JDBC 4.0的增强特性之二

Java SE 6中JDBC 4.0的增强特性之二

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

SQLException类现在支持Java SE链式异常机制(又称因果工具),它使我们能在一个JDBC操作中处理多条SQLException异常(如果后台数据库支持多条异常特性)。

作者:中国IT实验室 来源:中国IT实验室 2007年9月8日

关键字: JDBC java

  • 评论
  • 分享微博
  • 分享邮件

因果关系
    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-bin
set JAVA_HOME=C:\dev\java\jdk1.6.0
set DERBY_INSTALL=C:\dev\dbservers\db-derby-10.1.3.1-bin
set CLASSPATH=%CLASSPATH%;%DERBY_INSTALL%\lib\derby.jar;
                %DERBY_INSTALL%\lib\derbytools.jar;
                %DERBY_INSTALL%\lib\derbynet.jar;

cd %DERBY_INSTALL%\frameworks\NetworkServer\bin
startNetworkServer.bat



要连接数据库服务器并创建测试数据库,需开启另一个命令行窗口并运行以下命令。请确保DERBY_INSTALL和JAVA_HOME环境变量符合你本机的环境。

set JAVA_HOME=C:\dev\java\jdk1.6.0
set DERBY_INSTALL=C:\dev\dbservers\db-derby-10.1.3.1-bin
set CLASSPATH=%DERBY_INSTALL%\lib\derbyclient.jar;
                %DERBY_INSTALL%\lib\derbytools.jar;.

%JAVA_HOME%\bin\java org.apache.derby.tools.ij
connect '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查询。

public DataSet<LoanAppDetails> getAllActiveLoans() throws Exception {
        // Get Connection
        Connection conn = getConnection();
        LoanAppDetailsQuery query = null;
        DataSet<LoanAppDetails> loanDetails = null;
        query = QueryObjectFactory.createQueryObject(
                        LoanAppDetailsQuery.class, conn);
        loanDetails = query.getAllActiveLoans();
        return loanDetails;
}

public DataSet<LoanAppDetails> getLoanDetailsByBorrowerName(
                String borrFirstName, String borrLastName) throws Exception {
        // Get Connection
        Connection conn = getConnection();
        LoanAppDetailsQuery query = null;
        DataSet<LoanAppDetails> loanDetails = null;
        query = QueryObjectFactory.createQueryObject(
                        LoanAppDetailsQuery.class, conn);
        loanDetails = query.getLoanDetailsByBorrowerName(
                        borrFirstName,borrLastName);
        return loanDetails;
}



结论
    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实现代码。

    本文中,我们了解了RowId支持,JDBC驱动加载和基于标注的SQL等JDBC 4.0的增强特性。未来,JDBC 4.0还将增加更多特性以支持SQL:2003。请参阅特性文档,以获取更多有关JDBC 4.0特性的信息。


Srini Penchikala是Flagstar Bank的一位信息系统问题专家。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章