本文演示了如何将资源索引与 Apache Derby 数据库结合使用来开发
Eclipse 插件。嵌入到 Eclipse 的 Derby 数据库使您可以在客户端创建 SQL 数据库而不会有安全问题或网络问题,例如连接不稳定或反应时间长。SQL
数据库和 JDBC API 提供了一种轻松的方法用于存储信息和快速搜索先前存储的数据。
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 查询(有关详细信息的链接,请参阅 参考资料 部分)。
要安装这些插件,请执行以下步骤:
- 将文件从下载的软件包中解压缩到 Eclipse 插件目录中(例如,/eclipse/plugins)。
- 启动(或重新启动)Eclipse,并通过单击 Help > About Eclipse
SDK > Plug-in details 检验插件是否已经成功安装。您应当会在列表中看到 Derby 插件,如图
1 所示。
图 1. Eclipse 插件清单中的 Derby 插件
注:如果需要测试本文附带的示例应用程序,那么至少需要使用 Derby
内核插件。
测试 Derby 数据库插件功能的简单代码
现在可以创建一个简单的插件来演示 Derby 内核插件的功能。为此,请使用 Eclipse Plug-In
Project 向导创建一个名为 sample_derby 的新项目,该项目将基于 Hello World 模板(参见图 2)。
图 2. 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. 运行的资源索引器插件
可以通过双击列表中的条目来访问 Resource View 中的资源。在对工作区做出更改后,视图不会自动循环,但是您可以选择
Views > Refresh 来完成循环。
结束语
Eclipse 和 Apache Derby 目前是业内两个著名的开放源码项目。Eclipse
框架允许创建各种 GUI 应用程序,特别是 IDE 应用程序。Apache Derby 允许您为任何 Java 应用程序创建本地
SQL 数据库。并且正如本文所演示的,可以轻松地将 Eclipse 与 Derby 结合使用。
使用 Derby 数据库开发 Eclipse 插件的一个主要应用是资源索引。连同 Eclipse
Builder 框架一起使用,您可以将资源信息存储到 SQL 数据库中,然后通过查询使用这些信息。由于 Derby 数据库针对
SQL 查询做了优化,因此访问资源索引时可获得最佳性能。
下载
描述 |
名字 |
大小 |
下载方法 |
本文的样例项目
| samples.zip |
173KB |
HTTP |
参考资料
学习
获得产品和技术
- 使用
IBM 试用软件 改进您的下一个开放源码开发项目,这些软件可以通过下载或从 DVD 中获得。
讨论
|