天天看点

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
           
如果它不运行怎么办

尽管第一个数据库连接示例尽可能简单,但有时会出现问题。 每当使用Java编程语言时,最可能的问题是所需的类文件不在

CLASSPATH

。 例如,如果您的代码可以编译,但是

JDBC Driver org.apache.derby.jdbc.EmbeddedDriver not found in CLASSPATH

运行

JDBC Driver org.apache.derby.jdbc.EmbeddedDriver not found in CLASSPATH

时出现错误消息

JDBC Driver org.apache.derby.jdbc.EmbeddedDriver not found in CLASSPATH

,则您需要将derby.jar文件添加到

CLASSPATH

。 本系列的第一篇文章对此进行了讨论。 其他可能的错误是忘记使用

javac

工具编译Java源代码或将其放在错误的目录中。

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

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) ;
            }
        }
    }
}
           
那一个呢?

为了简单起见,本文仅专注于通过使用Derby嵌入式JDBC驱动程序连接到嵌入式Apache Derby数据库。 作为标准规则,用于连接数据库的首选JDBC解决方案是利用

DataSource

,它允许您抽象出数据库连接详细信息,例如数据库URL,驱动程序类,用户名,密码和数据库名。 通过抽象出特定的连接信息,您可以轻松更改那些参数,而无需更改数据库应用程序代码。 以后的文章将探讨Derby与

DataSource

结合使用。 但是,首先学习JDBC驱动程序和

DriverManager

,然后学习

DataSource

DriverManager

容易理解JDBC的基础。

此示例代码首先定义两个常量,这些常量包含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状态的前两个字符是类值,后三个字符形成子类值。 值为

00000

SQL状态表示成功,而值为

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数据库