java derby数据库_使用Apache Derby进行Java数据库开发,第1部分

java derby数据库

JDBC简介

以前,本系列文章通过使用ij工具连接Apache Derby数据库并与之交互来演示了许多数据库概念。 尽管当时可能还不太明显,但是您使用的Java应用程序使用JDBC应用程序编程接口(API)连接到嵌入式Apache Derby数据库并与之交互。 在接下来的几篇文章中,您将学习如何通过编写自己的Java应用程序来重新创建ij工具的基本功能。 本文重点介绍建立数据库连接以及处理潜在的数据库错误和警告。

在跳到Java代码之前,您可能首先对JDBC API的性质感到好奇。 JDBC是官方的Java数据库连接API,自从Java开发工具包1.1版发布以来一直存在。 JDBC API包含在java.sql包中,如果仔细看,您会发现该API主要是接口。 结果,创建数据库JDBC驱动程序的真正工作落在了必须提供实现这些接口的Java类的数据库供应商(或进取的第三方)上。 JDBC API的扩展提供了更高级的功能,并且可以在javax.sql包中找到。 接下来的几篇文章将介绍大多数标准JDBC包。 扩展将不得不等到基本知识被覆盖。

关于JDBC的最后一点:Java应用程序与数据库之间的连接由JDBC驱动程序控制。 最初,有四种类型的JDBC驱动程序,按其类型号区分:1、2、3或4。这些类型对应于Java应用程序与数据库进行通信的不同技术。 如今,大多数驱动程序(包括用于连接Derby数据库的驱动程序)都是Type 4驱动程序,这意味着它们完全用Java语言编写,并将JDBC API直接转换为特定于供应商的数据库协议。 对于Derby数据库,此过程得以简化,因为Derby是用Java语言编写的。

Apache Derby和JDBC

现在您已经熟悉了JDBC的基础知识,您可以开始学习如何使用Java编程语言连接到嵌入式Apache Derby数据库。 但是,首先,您必须已经可以正常安装Apache Derby数据库软件,如本系列第一篇文章中所述 。 如果您尚未执行此关键步骤,请重新阅读第一篇文章,然后下载并安装Derby软件。 安装Derby数据库软件之后,可以使用本文提供的示例代码连接到Derby数据库,如清单1所示。

清单1.执行示例代码
rb$ mkdir derbyWork
rb$ cd derbyWork/
rb$ unzip ../derby9.zip 
Archive:  ../derby9.zip
  inflating: FirstConnect.java       
rb$ ls    
FirstConnect.java
rb$ javac FirstConnect.java 
rb$ java FirstConnect 

----------------------------------------------------
Database Name    = Apache Derby
Database Version = 10.1.2.1
Driver Name      = Apache Derby Embedded JDBC Driver
Driver Version   = 10.1.2.1
Database URL     = jdbc:derby:test
----------------------------------------------------
rb$ java FirstConnect
SQLWarning: State=01J01, Severity = 10000
Database 'test' not created, connection made to existing database instead.

----------------------------------------------------
Database Name    = Apache Derby
Database Version = 10.1.2.1
Driver Name      = Apache Derby Embedded JDBC Driver
Driver Version   = 10.1.2.1
Database URL     = jdbc:derby:test
----------------------------------------------------
rb$ ls
FirstConnect.class      derby.log
FirstConnect.java       test

在第一个示例中,您将创建一个干净的工作区来开发和执行数据库应用程序代码。 首先,创建一个新目录,将本文提供的代码文件提取到其中。 在编译和执行之前,您使用ls命令演示该目录仅包含本文中介绍的Java源代码。

下一步是使用Java编译器创建Java字节码文件,该文件将在下一步中由Java虚拟机(JVM)执行。 如果成功编译了源代码,则可以在JVM中执行字节码。 这将调用FirstConnect类的main方法,该方法将生成与所示类似的输出。 如果您在使用过程中遇到问题,请参见侧边栏如果不运行怎么办 。 此Java代码首先创建测试数据库,然后使用Apache Derby嵌入式JDBC驱动程序创建与该数据库的连接。 为了演示此代码如何正确处理SQL警告和错误,您可以重新执行该代码,该代码首先显示警告信息,指示未创建数据库(因为它已经存在),然后显示有关数据库的标准信息和先前显示的JDBC驱动程序。

本示例以再次显示工作目录的内容作为结束,其中显示了已编译的Java类文件和新的数据库文件。 最后一点很重要:当您使用Apache Derby作为嵌入式数据库时,数据库文件的默认位置在代码所在的目录中。 如果这不是您想要的,则需要修改JDBC URL以指定应在何处创建数据库文件。 该主题不在本文讨论范围之内。 请查阅《 Derby开发人员指南》 ,该指南可通过本文“ 相关主题”部分中的Derby在线手册链接获得。

连接Java应用程序和Derby数据库

您在上一节中学习了如何执行的Java代码非常简单,本文的其余部分将详细介绍。 在生产环境中,开发Java数据库应用程序可能很困难。 本文并不会陷入这些细节中,而将在以后的文章中进行介绍,而是着重于在Java应用程序和嵌入式Apache Derby数据库之间建立连接的最基本技术。 如清单2所示,该技术需要使用JDBC驱动程序来实现连接协议。

清单2.使用JDBC连接到Derby数据库
private static final String driver = "org.apache.derby.jdbc.EmbeddedDriver" ;
private static final String url = "jdbc:derby:test;create=true" ;
 
public static void main(String[] args) {
    Connection con = null ;
    DatabaseMetaData dbmd = null ;
        
    try {
        Class.forName(driver) ;
        con = DriverManager.getConnection(url);
       
       // Use the database connection somehow.
       
    } catch (SQLException se) {
        printSQLException(se) ;
    } catch(ClassNotFoundException e){
        System.out.println("JDBC Driver " + driver + " not found in CLASSPATH") ;
    }finally {
        if(con != null){
            try{
                con.close() ;
            } catch(SQLException se){
                printSQLException(se) ;
            }
        }
    }
}

此示例代码首先定义两个常量,这些常量包含Apache Derby嵌入式JDBC驱动程序的Java类名称和JDBC数据库连接URL。 该连接URL应该看起来很熟悉-这正是您在ij工具中发出connect命令时使用的上一篇文章。 分配给driver的值是嵌入式驱动程序类的完全限定名称。

其余代码包含在main方法中。 它使用JVM中的默认类加载器来查找和实例化先前定义的driver类,这是通过使用Class.forname方法完成的。 此方法查找Derby嵌入式驱动程序的类文件,该文件必须存在于CLASSPATH某个位置,然后将其加载到JVM中。 在此加载过程中,将处理类的静态部分,该部分将此驱动程序注册到JDBC DriverManager对象。

DriverManager充当工厂对象。 给定数据库URL, DriverManager通过使用适当的JDBC驱动程序返回数据库连接。 在下一行代码中执行此步骤,在该行中,您将使用先前定义的URL向DriverManager请求JDBC connection

您无疑已经注意到连接请求被包装在try ... catch块中,并且您在finally块中的连接上调用了close方法。 本文后面的“ 出现问题时”部分将解决这两个主题。 给定空间限制,本文无法全面探讨使用JDBC建立数据库连接的不同方法。 例如,此示例未使用任何安全信息,例如用户名或密码。 以后的文章将探讨替代的数据库连接技术(例如,参见边栏“数据源怎么 ?”)。 如果您不能等到那时,请务必查看《 Derby开发人员指南》,该指南在本文的“ 相关主题”部分中链接到。

数据库元数据

如果您从未遇到过元数据,它可能看起来像一个奇怪的概念。 但实际上很简单: 元数据是描述数据的数据。 在数据库的上下文中,元数据描述该特定数据库,例如数据库的名称,其版本号或进行连接的JDBC驱动程序的名称。 您可以通过从DatabaseMetaData对象调用适当的方法来访问JDBC中的数据库元数据,如清单3所示。

清单3.使用数据库元数据
DatabaseMetaData dbmd = null ;
dbmd = con.getMetaData() ;

System.out.println("\n----------------------------------------------------") ;
System.out.println("Database Name    = " + dbmd.getDatabaseProductName()) ;
System.out.println("Database Version = " + dbmd.getDatabaseProductVersion()) ;
System.out.println("Driver Name      = " + dbmd.getDriverName()) ;
System.out.println("Driver Version   = " + dbmd.getDriverVersion()) ;
System.out.println("Database URL     = " + dbmd.getURL()) ;
System.out.println("----------------------------------------------------") ;

要访问适当的元数据,首先需要从当前的JDBC Connection创建一个新的DatabaseMetaData对象,如前面的示例所示。 然后,您可以调用Apache Derby JDBC驱动程序提供的许多元数据功能之一(有关完整列表,请参阅JDBC规范,您可以从本文的“ 相关主题”部分进行访问)。 在此示例中,您提取要访问的数据库的名称和产品版本号,用于访问该数据库的JDBC驱动程序名称和版本号以及标识要访问的数据库的完整JDBC URL。建立连接。 如果要开发必须与许多不同的数据库或JDBC驱动程序进行交互的数据库应用程序,则数据库元数据最有用。 在这种情况下,您可以使用元数据在运行时确定特定数据库和JDBC驱动程序的功能。

当出现问题时

当您与Apache Derby数据库一起工作时,或者跟随本系列中的前几篇文章一起学习或独自学习,无疑会遇到数据库警告和数据库错误。 鉴于您存储在数据库中的信息的重要性,正确处理数据库错误和警告对于您的业务至关重要。 幸运的是,如本节其余部分所述,这样做很简单。 第一步是学习如何查看提供给您的应用程序的有关数据库遇到的错误的信息,如清单4所示。

清单4.异常处理代码
private static void printSQLException(SQLException se) {
    while(se != null) {
        System.out.print("SQLException: State:   " + se.getSQLState());
        System.out.println("Severity: " + se.getErrorCode());
        System.out.println(se.getMessage());            
        
        se = se.getNextException();
    }
 }

private static void printSQLWarning(SQLWarning sw) {
    while(sw != null) {
        System.out.print("SQLWarning: State=" + sw.getSQLState()) ;
        System.out.println(", Severity = " + sw.getErrorCode()) ;
        System.out.println(sw.getMessage()); 
        
        sw = sw.getNextWarning();
    }
    }

如图所示,处理SQL异常和SQL警告是相似的。 SQLWarning类继承自SQLException类。 但是,SQL警告不如SQL异常严重,因此最好单独处理它们。 这两个函数都被声明为private static ,这使您可以从main方法中调用它们,而不能从其他类中调用它们。 在生产代码中,您将根据程序要求更改此设置。

在这两个功能中,您都会遍历警告或异常。 从正常的错误处理角度看,这似乎很奇怪,但是在进行数据库编程时,请期待意外的情况。 链接的原因很简单:事件通常在数据库中耦合。 例如,如果您要在数据库中插入多行,并且由于列数据类型或名称不匹配而使它们全部失败,则可能有多个错误。 为了正确解决所有这些问题,您需要能够将异常绑定在一起,以便将数据库遇到的所有问题通知调用代码。 为了使事情变得容易,Apache Derby始终将最重要的异常放在任何异常链中的第一位。

在循环内部,您可以打印出错误或警告信息。 SQL状态是一个五个字符的字符串,遵循X / OPEN通用应用程序环境(CAE)规范,数据管理:SQL,版本2 SQL规范或SQL99标准约定,并允许程序从特定的数据库错误条件中恢复。 SQL状态的前两个字符是类值,后三个字符形成子类值。 值为00000SQL状态表示成功,而值为01的类状态表示警告条件,例如数据截断。 SQL代码是特定于数据库的值。

处理SQL异常很简单。 您使用标准的Java try ... catch机制来包装JDBC方法调用,如清单5所示。

清单5.捕获SQL异常
try{
    // Execute a JDBC operation
} catch (SQLException se) {
    printSQLException(se) ;
}

如该示例代码所示,您可以通过将SQLException对象传递给先前定义的printSQLException方法来处理所有SQL异常,该方法将处理所有错误报告。 处理SQL异常的唯一主要困难是正确回收数据库资源,例如数据库连接。 因为可以在运行数据库应用程序代码的JVM外部管理这些资源(如连接或任何数据库游标),所以您的应用程序必须显式关闭它们。 Connection对象的close方法可能会引发SQLException ,因此您可以将该方法放在finally块中,以确保Java应用程序即使发生错误也尝试关闭数据库连接。

另一方面,您必须显式检查所有SQL警告,因为它们不会通过标准的异常处理机制传播。 为此,请在相关的JDBC对象上调用适当的getWarnings方法,如清单6所示。

清单6.检查SQL警告
SQLWarning swarn = con.getWarnings() ;

if(swarn != null){
    printSQLWarning(swarn) ;
}

如前所述,SQL警告由printSQLWarning方法处理。 在调用该方法之前,您首先要检查至少有一个SQL警告; 如果是这样,则将第一个SQLWarning对象传递给适当的方法。 正如您将在以后的文章中看到的那样,许多JDBC对象可以生成SQL警告,因此封装错误和警告处理代码可以简化开发和维护数据库应用程序代码的任务。

放在一起

到目前为止,本文已经讨论了通过将JDBC API与Apache Derby一起使用来建立数据库连接所需的许多组件。 这些片段一起提供了大多数必要的功能,如清单7中提供的完整连接示例所示。

清单7.完整的连接示例代码
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.DatabaseMetaData;

public class FirstConnect {
    private static final String driver = "org.apache.derby.jdbc.EmbeddedDriver" ;
    private static final String url = "jdbc:derby:test;create=true" ;
    
    static void printSQLException(SQLException se) {
        while(se != null) {

            System.out.print("SQLException: State:   " + se.getSQLState());
            System.out.println("Severity: " + se.getErrorCode());
            System.out.println(se.getMessage());            
            
            se = se.getNextException();
        }
    }
        
    static void printSQLWarning(SQLWarning sw) {
        while(sw != null) {

            System.out.print("SQLWarning: State=" + sw.getSQLState()) ;
            System.out.println(", Severity = " + sw.getErrorCode()) ;
            System.out.println(sw.getMessage()); 
            
            sw = sw.getNextWarning();
        }
    }

    public static void main(String[] args) {
        Connection con = null ;
        DatabaseMetaData dbmd = null ;
        
        try {
            Class.forName(driver) ;
            con = DriverManager.getConnection(url);

            SQLWarning swarn = con. getWarnings() ;
            
            if(swarn != null){
                printSQLWarning(swarn) ;
            }
            
            dbmd = con.getMetaData() ;
            
            System.out.println("\n----------------------------------------------------") ;
            System.out.println("Database Name    = " + dbmd.getDatabaseProductName()) ;
            System.out.println("Database Version = " + dbmd.getDatabaseProductVersion()) ;
            System.out.println("Driver Name      = " + dbmd.getDriverName()) ;
            System.out.println("Driver Version   = " + dbmd.getDriverVersion()) ;
            System.out.println("Database URL     = " + dbmd.getURL()) ;
            System.out.println("----------------------------------------------------") ;
            
        } catch (SQLException se) {
            printSQLException(se) ;
        } catch(ClassNotFoundException e){
            System.out.println("JDBC Driver " + driver + " not found in CLASSPATH") ;
        }
        finally {
            if(con != null){
                try{
                    con.close() ;
                } catch(SQLException se){
                    printSQLException(se) ;
                }
            }
        }
    }
}

此类是通过JDBC建立与嵌入式Apache Derby数据库的数据库连接所需要的,而这正是在本文开头编译并执行的示例代码中所提供的。 新的主要代码是在程序代码顶部包含五个import语句。 尽管可以使用import java.sql.* ,但是单独列出每个import语句可以使您明确意识到在应用程序中使用的JDBC对象。

该应用程序包括清单4中讨论的错误处理功能。 所有数据库操作都封装在一个try ... catch块中,包括清单3中所示的数据库元数据操作。 许多数据库应用程序都避免了数据库应用程序代码和数据库之间的紧密耦合,从而简化了应用程序和数据库的管理和维护。 但是,考虑到Apache Derby数据库的嵌入式功能,应用程序和数据库之间的界限变得模糊了,不需要严格地执行这种分离。

摘要

在本文中,您学习了如何编写连接到嵌入式Apache Derby数据库的Java应用程序。 此过程使用Apache Derby项目中的Type 4 JDBC驱动程序连接到数据库,从数据库中提取元数据,然后关闭数据库连接。 您还学习了如何处理Java应用程序中Derby可能生成SQL警告和SQL异常。 以后的文章将基于本文介绍的技术来向Derby数据库发出查询并在Java应用程序中处理结果。


翻译自: https://www.ibm.com/developerworks/opensource/library/os-ad-trifecta9/index.html

java derby数据库

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值