使用 Apache Derby 开发 Eclipse 插件

使用资源索引的演示

本文演示了如何将资源索引与 Apache Derby 数据库结合使用来开发 Eclipse 插件。嵌入到 Eclipse 的 Derby 数据库使您可以在客户端创建 SQL 数据库而不会有安全问题或网络问题,例如连接不稳定或反应时间长。SQL 数据库和 JDBC API 提供了一种轻松的方法用于存储信息和快速搜索先前存储的数据。

Artem Papkov (artem@us.ibm.com), 解决方案架构师, IBM

Artem Papkov 目前担任 IBM 的 Client Innovation Team 的解决方案架构师,辅助客户及业务伙伴在业务中采用新兴技术,比如 SOA 和 Web 服务。他于 1998 年毕业于 Belarusian State 大学的信息学和无线电电子学,获得计算机科学硕士学位。他于 2000 年加入位于北卡罗莱纳州的 IBM Research Triangle Park。他的工作经验包括利用新兴技术进行多层解决方案的软件开发、架构设计和基于 Internet 解决方案的集成。在过去三年中,他一直致力于紧密联系客户,帮助他们采用 Web 服务作为 IBM 策略集成技术,并采用 SOA 作为集成方法。



Jim Smith (jamessmi@us.ibm.com), 经理, IBM

Jim Smith 有 18 年以上的软件开发经验。他在加利福尼亚州利佛莫尔的 Sandia National Labs 开始了他的职业生涯,负责使用各种已有的传统代码来设计高速数据采集系统和分布式计算系统。在具备了 Java 语言和客户沟通技巧方面的丰富经验后,Jim 转到了 Emerging Internet Technologies 团队,专注于为 IBM 客户实现 Java 解决方案。Jim 是 Advanced Technology Solutions (ATS) 的创始人之一,该组织是一个全球软件服务与开发组织,其使命是为 IBM、开发实验室、业务伙伴和客户开发、完善与授权高级技术和轻量级业务过程,从而更加快速地采用和开发标准技术和 IBM 产品。目前,Jim 管理着该组织。



Terry Finch (terryfin@us.ibm.com), IT 专家, IBM, Intel, Microsoft,HP

Terry Finch 是 Customer Innovation Team 中的 IT 专家,负责领导涉及新技术和新兴技术的客户项目。自 2000 年受雇以来,Terry 已经成功地完成了大量项目,包括 IBM WebSphere® Portal 软件、IBM Lotus® Domino® 软件、Java 技术、XML、Web 服务、富 Internet 应用程序等等。最近,Terry 一直在研究富用户接口技术,例如 Macromedia Flex、Laszlo、IBM Workplace Client Technologies (IWCT) 和 Web 2.0 技术(如 Ajax 和 QEDWiki)。



2007 年 2 月 16 日

Apache Derby 和 Eclipse 插件

Eclipse 是一个功能强大的 IDE 平台,支持用于创建 GUI 组件(例如 SWT 或 JFaces)或用于处理数据(例如 Eclipse Modeling Framework)的许多框架。Eclipse 最令人兴奋的一个功能是能够通过创建新插件扩展 IDE 平台的功能。Eclipse 既支持以上提及的框架来进行插件开发,又支持许多其他常用框架(包括 Apache Derby 数据库)。

本文向您展示了如何在使用资源索引的情况下使用 Derby 数据库进行 Eclipse 插件开发。嵌入到 Eclipse 中的 Derby 数据库使您可以在客户端创建 SQL 数据库而不会有任何安全问题或网络问题,例如连接不稳定或反应时间长。SQL 数据库和 JDBC API 提供了一种轻松的方法用于存储信息和快速搜索先前存储的数据。

您将了解到关于下列主题的内容:

  • 将 Derby 数据库集成到 Eclipse 平台上
  • 使用 Derby 数据库处理 Eclipse 中的数据
  • 使用 Eclipse Builder 框架进行资源索引

入门

要开始在 Eclipse 中使用 Derby 数据库,第一步是 下载 Derby Eclipse 插件。选择 Latest Official Release 部分下的链接。您将在软件包中找到以下三个插件:

  • Derby 内核插件,它为 Eclipse 平台提供 Derby 支持
  • Derby 用户界面 (UI) 插件,它为在 Eclipse 平台中使用 Derby 数据库提供 UI 组件
  • Derby UI 文档插件,它为 UI 插件提供文档

Derby 内核插件允许使用 Derby 服务器和客户机库。因此,您既可以在 Eclipse 中创建 Derby 数据库,又可以连接至现有数据库。Derby UI 插件将提供在开发使用 Derby 数据库的应用程序时有用的组件和工具。例如,此插件允许您连接至现有数据库以及向数据库发送 SQL 查询(有关详细信息的链接,请参阅 参考资料 部分)。

要安装这些插件,请执行以下步骤:

  1. 将文件从下载的软件包中解压缩到 Eclipse 插件目录中(例如,/eclipse/plugins)。
  2. 启动(或重新启动)Eclipse,并通过单击 Help > About Eclipse SDK > Plug-in details 检验插件是否已经成功安装。您应当会在列表中看到 Derby 插件,如图 1 所示。
图 1. Eclipse 插件清单中的 Derby 插件
Eclipse 插件清单中的 Derby 插件

:如果需要测试本文附带的示例应用程序,那么至少需要使用 Derby 内核插件。

测试 Derby 数据库插件功能的简单代码

现在可以创建一个简单的插件来演示 Derby 内核插件的功能。为此,请使用 Eclipse Plug-In Project 向导创建一个名为 sample_derby 的新项目,该项目将基于 Hello World 模板(参见图 2)。

图 2. Eclipse Hello World 插件创建向导
Eclipse Hello World 插件创建向导

最初的 Hello World 插件只创建一个名为 Sample Menu 的 Eclipse 菜单元素和一个 Sample Action 菜单项。当用户单击此菜单项时,Hello World! 对话框将弹出。该插件还允许从 Eclipse 工具栏调用对话框。要查看其运行方法,请在 plugin.xml 文件编辑器的窗口中单击 Run an Eclipse application 链接,或者单击 Eclipse 工具栏中的 Run 按钮并使用 Eclipse application 配置调用它。

向新创建的插件中添加 Derby 支持即是指定 Derby 内核插件上的依赖性。您可以通过在打开 sample_derby 项目中打开 plugin.xml 文件,然后在 Dependencies 选项卡的 Required Plug-ins 部分种选择与 org.apache.derby.core 的依赖性来完成指定操作(参见图 3)。完成后,插件就可以使用 Derby 类。

图 3. 插件依赖性编辑器
插件依赖性编辑器

现在您可以了解如何通过扩展插件为本地数据库的 Records 表提供简单的记录计数器来操作简单的 Derby 数据库。此表包含关于数据库中保存的记录数目的信息。单击按钮后,记录数加一,并且显示具有当前记录数的对话框。首先,打开定义负责 Sample Action 的类的 SampleAction.java 文件,然后创建一个名为 queryRecords 的新方法。此时,您还只能连接至现有数据库。或者,如果相应的数据库不存在,系统将创建一个新数据库并始终返回 0(参见清单 1)。

清单 1. Derby 初始化代码
public class SampleAction implements IWorkbenchWindowActionDelegate {
/* ...code skipped here... */

/** driver string. */
private static final String DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
/** protocol string. */
private static final String PROTOCOL = "jdbc:derby:";
/** database name string. */
private static final String DATABASE = "sampleDB";

/** SQL script for creating Categories table. */
private static final String CREATE_TABLE = "CREATE TABLE Records" 
     + "("
     + "quantity int"
     + ")";

/* ...code skipped here... */

/**
* Connects to database, inserts one record into Records table 
* and then counts total records quantity in database.
* If database does not exist, then new database is created.  
*/
private int queryRecords()
        throws SQLException, IllegalAccessException, ClassNotFoundException,
        InstantiationException {

    Connection currentConnection = null;
    System.setProperty("derby.system.home",
        Sample_derbyPlugin.getDefault().getStateLocation().toFile().getAbsolutePath());
    Properties props = new Properties();

    try {
        Class.forName(DRIVER).newInstance();
        currentConnection = DriverManager.getConnection(PROTOCOL 
            + DATABASE, props);

    } catch (SQLException sqlException) {
        //trying to create database
        currentConnection = DriverManager.getConnection(PROTOCOL 
            + DATABASE + ";create=true", props);
        try {
            Statement s = currentConnection.createStatement();
            try {
                s.execute(CREATE_TABLE);
            } finally {
                s.close();
            }
            currentConnection.commit();
        } catch (SQLException ex) {
            currentConnection.close();
            throw ex;
        }
    }
    return 0;
}

在这里,系统属性 derby.system.home 对应的是 Derby 系统文件的位置。在 清单 1 中,系统属性被设为工作区目录内的插件数据文件夹 .metadata/.plugins/sample_derby。

要检验查询函数是否成功地建立了连接,必须通过添加以下代码来更改同一个 Java 源文件中的运行方法(参见清单 2)。

清单 2. 显示信息对话框
MessageDialog.openInformation(
window.getShell(),
"Sample_derby Plug-in",
"We have " + queryRecords() + " Records in the database");

注意 queryRecords 方法抛出异常,您只能通过使用 try-catch 结构并显示错误消息对话框来处理。

调用 Sample Action 程序后,您将看到系统显示以下对话框(参见图 4):

图 4. 运行的样例应用程序
运行的样例应用程序

接下来,需要将 INSERT/SELECT 查询添加到应用程序中。清单 3 中显示的代码只将新条目添加到 Records 表中,计算并返回记录数目。将下面几行添加到 Java 文件的开头。

清单 3. Derby 查询声明
/** SQL query that counts number of records in database    */
private static final String SELECT_RECORDS_QUERY = 
        "SELECT SUM(quantity) FROM Records";
    
/** SQL script that adds new record into database    */
private static final String INSERT_RECORDS_QUERY = 
        "INSERT INTO Records (quantity) VALUES(1)";

接下来,将下列代码添加到 queryRecords 方法的末尾。

清单 4. Derby 查询用法示例
int result = 0;
try {
    Statement s = currentConnection.createStatement();
    try {
        s.execute(INSERT_RECORDS_QUERY);
        ResultSet rs = s.executeQuery(SELECT_RECORDS_QUERY);
        if (rs.next()) {
            result = rs.getInt(1);
        }
    } finally {
        s.close();
    }
    currentConnection.commit();
} finally {
    currentConnection.close();
}
return result;

当 Eclipse 建立了与数据库的连接后,它将在 Records 表中插入一个新行,计算表中的记录数目,并返回此数目。因而,记录数目将随每次触发 Sample Action 而增长。多次调用应用程序后,应当会看到类似图 5 所示的对话框:

图 5. 运行的样例应用程序
运行的样例应用程序

现在,您看到了如何在 Eclipse 插件内使用内部 Derby 数据库的快速演示。接下来让我们去了解如何将插件用于更复杂的应用程序。


资源索引插件

资源索引功能对于 IDE 来说十分重要。要了解其原因,您可以看一看 C/C++ Development Tooling (CDT) Eclipse 插件:安装它,创建一个具有几个源文件的简单 C++ 项目,添加一对 #includes,然后尝试使用自动完成功能。您将看到找到自动完成的所有变化需要花好几秒钟,即便是小项目。此外,此操作将消耗 Eclipse 的所有资源,导致临时冻结。

本文附带了即用的样例资源索引器应用程序。它将监视由插件定义并具有名为 Sample Nature 特性的 Eclipse 工作区的项目中的所有资源(文件)(有关详细信息,请参阅 参考资料)。应用程序将把关于资源的信息存储到 Derby 数据库中并将提供一个允许您搜索文件的名为 Resources View 的视图。

在此部分中,您将亲历创建应用程序的主要步骤。开发 Eclipse 插件 GUI 这类典型步骤将被忽略,您将重点关注于用 Derby 进行插件开发。

连接池数据源管理器

由于是通过 JDBC 访问 Derby 数据库,因此最好使用 Derby 的 ConnectionPoolDataSource 接口实现管理数据库连接。ConnectionPoolDataSource 始终保持若干个与数据库的开放连接,因此无需在每次需要操作数据库时都打开新连接,从而加速了进程。另外,ConnectionPoolDataSource 避免了在应用程序同时打开与数据库的若干个连接的情况下发生冲突。

您将使用 Derby JDBC 驱动程序附带的名为 EmbeddedConnectionPoolDataSource 的类。在清单 5 中,创建 PerUserPoolDataSource 类的一个实例并将 EmbeddedConnectionPoolDataSource 类的实例设为其连接池数据源。

清单 5. 初始化 Derby 数据源
/**
* Datasource to use for connection.
*/
private static PerUserPoolDataSource datasource;

/**
* Initializes database and creates datasource instance for it.
*/
public static void initDatasource () {
    EmbeddedConnectionPoolDataSource connectionPoolDatasource;

    connectionPoolDatasource = new EmbeddedConnectionPoolDataSource(); 
    connectionPoolDatasource.setDatabaseName(
        ResourcesIndexerPlugin.getDefault().getStateLocation().
        toFile().getAbsolutePath() + "/resourcesDB");
    connectionPoolDatasource.setCreateDatabase("create");
        
    datasource = new PerUserPoolDataSource();
    datasource.setConnectionPoolDataSource(connectionPoolDatasource);
    datasource.setDefaultAutoCommit(false);
        
    try {
        Connection connection = datasource.getConnection();
        try {
            Statement statement = connection.createStatement();
            // searching for Resources table in database and 
            // if there is no one then initialize database
            try {
                statement.execute("SELECT 1 FROM  ");
            } catch (SQLException ex) {
                ResourcesDatabaseInitializer.initDatabase(connection);           
            } finally {
                statement.close();
            }
            connection.commit();
        } finally {
            connection.close();
        } catch (SQLException ex) {
            // Error handling here
        }
    }
}

测试 Derby 数据库插件功能的简单代码 部分描述的测试应用程序中,使用 derby.system.home 系统属性来指定 Derby 系统文件的位置。但是,在这段代码中,setDatabaseName 方法将同一个位置处理为数据库名称的一部分。当初始化数据源的过程完成后,清单 5 中所示的代码将查看 Resources 表是否存在于数据库中。如果该表不存在,则它调用数据库初始化代码 ResourcesDatabaseInitializer,该代码在此示例中是初始化数据库的实用程序类。在初始化 Eclipse 插件的过程中将调用 initDatasource 方法,因此数据源变量被初始化并可用于使用数据库。

数据库操纵层

创建资源索引插件的第二步是实现数据库操纵层。此层负责各种操作,例如插入、删除或查询信息。清单 6 是将新资源添加到 Resources 数据库的示例方法。

清单 6. 数据操纵
/**
* Adds resource entry in database
* @param resource resource to add into database
* @throws SQLException if SQL error occurred
*/
public static final void addResource(ResourceEntity resource) throws SQLException {
    Connection connection = datasource.getConnection();
    try {
        PreparedStatement s = connection.prepareStatement(
                "INSERT INTO Resources (path, name, project) VALUES(?,?,?)");
        try {
            s.setString(1, resource.getResourcePath());
            s.setString(2, resource.getResourceName());
            s.setString(3, resource.getProjectName());
            s.execute();
        } finally {
            s.close();
        }
        connection.commit();
    } finally {
        connection.close();
    }
}

本例使用了原始的数据库架构和十分简单的查询。实际的应用程序需要操纵更复杂的数据,以便获得所需的性能来使用设计良好的数据库模式和 SQL 查询。

使用构建程序来建立资源索引

建立资源索引的最佳方法是使用构建程序。在 Eclipse 中,构建程序是与特定的项目本性相关联的。项目中每发生一次更改(例如创建、删除或资源更新),都是由构建程序来处理。构建程序还为整个项目处理完整重新构建 任务和清除 任务。

要将构建程序支持添加到 Eclipse 插件中,可以使用 Project Builder and Nature 扩展向导。这将创建与其相关联的一个本性和构建程序。在本文附带的样例应用程序中,该本性被命名为 Sample Nature。为了处理项目中越来越多的更改,需要实现 IResourceDeltaVisitor 接口(参见清单 7)。

清单 7. IResourceDeltaVisitor 实现示例
public boolean visit(IResourceDelta delta) throws CoreException {
    IResource resource = delta.getResource();

    /* ...code skipped here... */

    switch (delta.getKind()) {
        case IResourceDelta.ADDED:
            DatabaseUtil.addResource(resource);
        break;
        case IResourceDelta.REMOVED:
            DatabaseUtil.removeResource(resource);
        break;
    }

    /* ...code skipped here... */

}

清单 7 中处理了两个操作:向工作区中添加资源和从数据库中删除资源。很明显,这只是一个示例,而您可以查找其他更复杂的使用以获得类似实现。

当构建程序就绪后,可以将 Sample Nature 添加到项目中以建立资源索引。此索引可以用于任何 Eclipse 应用程序代码中,方法是调用 数据库操纵层 部分中讨论的各个方法。

测试样例应用程序

要测试本文附带的样例插件,请将其安装到 Eclipse 中(包括还安装 Derby 插件)。然后通过在项目上单击鼠标右键并使用 Add/Remove Sample Nature 菜单项,将 Sample Nature 与工作区中所需的项目关联起来。系统将立即为所有来自受监视项目的资源建立索引。

要搜索索引文件,可以使用 Resource View。通过选择顶部菜单命令 Window > Select View > Other 打开 Resource View,然后在 Resources 视图组找到并选择 Resources View。搜索是按文件名的开头来执行的,因此应当会看到如图 6 所示的内容。

图 6. 运行的资源索引器插件
图 6. 运行的资源索引器插件

可以通过双击列表中的条目来访问 Resource View 中的资源。在对工作区做出更改后,视图不会自动循环,但是您可以选择 Views > Refresh 来完成循环。


结束语

Eclipse 和 Apache Derby 目前是业内两个著名的开放源码项目。Eclipse 框架允许创建各种 GUI 应用程序,特别是 IDE 应用程序。Apache Derby 允许您为任何 Java 应用程序创建本地 SQL 数据库。并且正如本文所演示的,可以轻松地将 Eclipse 与 Derby 结合使用。

使用 Derby 数据库开发 Eclipse 插件的一个主要应用是资源索引。连同 Eclipse Builder 框架一起使用,您可以将资源信息存储到 SQL 数据库中,然后通过查询使用这些信息。由于 Derby 数据库针对 SQL 查询做了优化,因此访问资源索引时可获得最佳性能。


下载

描述名字大小
本文的样例项目samples.zip173KB

参考资料

学习

获得产品和技术

  • 使用 IBM 试用软件 改进您的下一个开放源码开发项目,这些软件可以通过下载或从 DVD 中获得。

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Open source, Information Management
ArticleID=194768
ArticleTitle=使用 Apache Derby 开发 Eclipse 插件
publish-date=02162007