级别: 中级 王飞鹏 (wangfp@cn.ibm.com), 软件工程师,
IBM
王雪飞 (wangxfei@cn.ibm.com), 高级软件工程师,
IBM
肖静静 (xiaojj@cn.ibm.com), 软件工程师,
IBM
2008 年 10 月 10 日 DB2 Everyplace 作为 DB2 家族的成员,它使用服务器同步机制将企业数据传递到移动和嵌入设备端,从而让移动性较大的专业人员能在办公室以外的地方获取他们所需要的企业数据。不仅如此,驻留在移动设备上的 DB2 Everyplace 移动数据库作为关系型数据库为使用者提供了安全高效的数据管理功能,使用者可以存取移动设备上的数据库并对其执行更新并将更新后的数据传回企业数据库使得企业数据库与移动数据库保持一致。
简介
本文将带领读者在 symbian 平台(Nokia Series80)上使用 DB2 Everyplace 所提供的 API 来创建一个基于 Java 的简单的 DB2 Everyplace 应用程序。在这个样例应用中,我们将用 JDBC 接口来创建一个样例移动数据库并执行增删改的操作。随后,我们将使用 DB2 Everyplace 的 Java 同步 API 开发同步应用,以用来和 DB2 Everyplace 同步服务器进行双向同步。
前提条件
- DB2 Everyplace 以及 J2ME 的基础知识
- 操作系统 Windows XP Service Pack2 或以上
- DB2 Everyplace Enterprise Edition 8.2 以上
- Nokia PC suite
- Eclipse 3.0 以上
背景知识
DB2 Everyplace 技术
DB2 Everyplace 为手持设备提供数据服务。手持设备既可以在线读取和更新后台源数据,又可以在离线时管理本地数据。由此将数据服务从后端的业务数据库扩展到前端的手持设备端,使得前端与后端的数据进行无缝连接,使得现今的电子化商务可以更加高效与准确。
作为 IBM 普适计算解决方案的一部分,DB2 Everyplace 由下面三个部分组成:(见图1)
- DB2 Everyplace 移动数据库。作为嵌入式的关系型数据库,DB2 Everyplace 移动数据库允许不同的手持设备上上的数据可以存放在数据库中进行管理。
- DB2 Everyplace 同步客户端。DB2 Everyplace 同步客户端运行于手持设备端负责移动数据库与同步服务器进行同步。
- DB2 Everyplace 同步服务器。作为企业数据源与手持设备移动数据库之间的桥梁,DB2 Everyplace 同步服务器运行于服务器端,并负责管理业务数据库与手持设备上的移动数据库进行双向的数据同步。
图 1. DB2 Everyplace 的三个部件以及源数据库之间的交互
开发环境配置
配置开发环境的步骤如下:
- 下载并安装 Eclipse,本文中使用 Eclipse 版本 3.3.2
- 下载并安装 J2SE 软件开发包,本文中使用 JDK 1.5
- 下载并安装最新的 DB2 Everyplace,本文中所使用的是 DB2 Everyplace 版本 9.1
服务器配置
首先我们需要启动 DB2 Everyplace 同步服务器(如果是 Windows 平台可以通过双击“MS Windows Start menu->All Programs->IBM DB2 Everyplace->Enterprise Edition 9.1->Administration Tools->Start Servlet for SyncServer”来启动)。接下来我们还需要启动移动设备管理中心来完成服务器端的配置。本文中使用的 DB2 Everyplace 同步服务器的 IP 地址是 9.181.135.112(读者请根据自己同步服务器的 IP 地址来进行替换)。接下来我们还需要在移动设备管理中心中配置一些必须的预定,预定集同步组以及同步用户的具体信息
- 在移动设备管理中心创建一个名为 syncGrp 的用户组
- 在移动设备管理中心创建一个名为 syncUser 的用户(密码设置为 syncPass)并将该用户加入到在 1# 中创建的 syncGrp 用户组
- 创建一个名为 syncSubs 的预定集
- 创建一个名为 syncSub 的预定并将源数据库中的 stbl 表作为源表加入到预定中(见清单1)
- 将预定 syncSub 放入 syncSubs 预定集
清单 1. 源表创建语句
CREATE TABLE STBL(
"IDX" INTEGER NOT NULL ,
"STRDESC" VARCHAR(10) NOT NULL)
|
创建一个 Java 项目
- 打开Eclipse,双击“文件->新建->项目",填入项目名称并点击下一步(见图2)
图 2. 创建 Java 项目
- 点击"完成"(见图3)
图 3. 完成项目创建
加入 sync API 和 JDBC API 支持
- 在 Project Explorer 视图中, 进入 Project 菜单,选择 Properties 并单击 Add External JARs。加入 isync4j.jar, jdbc.jar 和 db2ejdbc.jar (见图4)
图 4. 加入 sync API 和 JDBC API
- 单击OK,完成配置 (见图5)
图 5. 已加入的库文件
从配置文件读取配置信息
syncsample 样例程序通过读取一些属性设置来初始化。这些属性可以通过配置文件来指定,以达到程序方便维护的目的。在当前的例子里面,文件 db2sync_db2e.properties 用来存放属性设置。下面的程序中,方法 readProperties 用来读取 db2sync_db2e.properties 中的属性并存放到名字为 userProps 的 Java Properties 实例中。值得注意的是属性 server.url,isync.user和isync.password。确认 server.url 的主机名是正在运行的 sync server 的 IP 地址。确认 isync.user 和 isync.password 是在 MDAC 中指定的用于同步的用户名和密码。(见清单2和清单3)
清单 2. db2sync_db2e.properties 文件
syncdriver=com.ibm.mobileservices.isync.db2e.jni.DB2eISyncProvider
syncprotocol=isync:db2e:
server.url=http://9.181.135.112:8080
target.db.driver=com.ibm.db2e.jdbc.DB2eDriver
target.db.url=jdbc:db2e:
isync.user=syncUser
isync.password=syncPass
isync.timeout=60
isync.trace=default
# directory for configuration information
path=data
# directory for data
jdbcsuburl=.
# e.g. filesubdir
filesubdir=.
|
清单 3. readProperties 方法
private void readProperties(String propFile)
{
try
{
configProps =(PropertyResourceBundle)ResourceBundle.getBundle(propFile);
userProps.put("syncdriver",configProps.getString("syncdriver"));
userProps.put("syncprotocol", configProps.getString("syncprotocol"));
userProps.put("server.url", configProps.getString("server.url"));
userProps.put("target.db.driver",configProps.getString("target.db.driver"));
userProps.put("target.db.url",configProps.getString("target.db.url");
userProps.put("isync.user", configProps.getString("isync.user"));
userProps.put("isync.password",configProps.getString("isync.password"));
userProps.put("isync.timeout",configProps.getString("isync.timeout"));
userProps.put("isync.trace", configProps.getString("isync.trace"));
userProps.put("path", configProps.getString("path"));
userProps.put("jdbcsuburl", configProps.getString("jdbcsuburl"));
userProps.put("filesubdir",configProps.getString("filesubdir"));
}
catch (MissingResourceException mre)
{throw mre;}
} //readProperties
|
实现 ISyncListener 接口
为了让同步应用可以在同步进行当中接收到事件通知,sync API 提供了一个名为 ISyncListener 的回调接口。同步应用只需要实现这个接口并向同步引擎注册该接口实例就可以了。在下面的代码中,类 SyncListener 用来实现 ISyncListener 接口。(见清单4)
清单 4. 类 SyncListener 的源代码
package syncapp;
import java.sql.*;
/*
Import the ISync Java Client Package
*/
import com.ibm.mobileservices.isync.*;
import com.ibm.mobileservices.isync.event.*;
public class SyncListener implements ISyncListener {
/*
Implement the eventIssued() method in the ISyncListener
interface if you are interested in event notification (optional)
*/
public int eventIssued(ISyncEvent evt)
{
int evtType = evt.getEventType();//获得事件类型
int evtCode = evt.getEventCode();//获得事件代码
switch(evtType)
{
// 针对事件类型进行相应处理
case ISync.EVTTYPE_INFO:
case ISync.EVTTYPE_ERROR:
...
return ISync.RTNCB_DONE;
case ISync.EVTTYPE_RETRY:
...
case ISync.EVTTYPE_CONFLICT:
...
}//end switch
}// end eventIssued
}// end class SyncListener
|
同步应用开发
本节将会展示如何编写同步应用程序 SyncMain。SyncMain 首先从配置文件 db2sync_db2e.properties 中读取属性设置来初始化同步引擎。为了在同步进行中应用可以接收到引擎的事件通知,SyncMain 创建了一个 SyncListener 实例作为事件的监听器。最后,启动同步引擎开始和服务器进行双向同步。(见清单5)
清单 5. SyncMain.java
package syncapp;
import java.sql.*;
import java.util.*;
import com.ibm.db2e.jdbc.*;
/*
Import the ISync Java Client Package
*/
import com.ibm.mobileservices.isync.*;
public class SyncMain {
// Synchronization 对象
private ISyncProvider provider;
private ISyncService service;
private ISyncConfigStore config;
private ISyncDriver syncer;
// Synchronization 参数
private static PropertyResourceBundle configProps;
private Properties userProps = new Properties();
private ISyncSubscriptionSet ssArr[] = null;
private void readProperties(String propFile)
{
...
} //readProperties
public void runSample(String propFile)
{
// 读属性文件配置
readProperties(propFile);
// 加载sync driver
Class.forName(userProps.getProperty("syncdriver"));
// 获得synchronization service的实例
provider = ISyncManager.getISyncProvider(userProps.getProperty("syncprotocol"));
service = provider.createSyncService(userProps.getProperty("server.url"), userProps);
// 获得configuration store的实例
config = service.getConfigStore(userProps.getProperty("path"));
// 获得 sync driver 的实例
syncer = config.getSyncDriver();
// 注册事件监听器的
syncer.setSyncListener(new SyncListener());
// 启动同步
rc = syncer.sync();
...
} //runSample
public static void main (String[] args)
{
if (args.length == 1)
{
SyncMain sample = new SyncMain();
sample.runSample(args[0]);
}
else
System.out.println("Usage: java ISyncSample property_file");
}
}
|
移动数据库应用开发
JDBC 是结合 Java 编程语言和 SQL 语句的不依赖于特定数据库的业界标准。该部分将介绍如何开发移动数据库应用 JdbcMain。与基于 SQL 的数据库的其他访问方法类似,JdbcMain 采用 JDBC 接口通过 DB2 Everyplace 数据库引擎访问数据。在 JdbcMain 的应用中,类 JdbcMain 先执行一条插入语句,它会将一条记录插入到表 stbl 中。然后,查询表 stbl 中的所有记录。所以,当查询执行结束,刚被插入的记录也应该在返回的查询结果集中。(见清单6)
清单 6. JdbcMain.java
package syncapp;
import java.sql.*;
import com.ibm.db2e.jdbc.DB2eDataSource;
public class JdbcMain {
public void runSQL()
{
String url = "jdbc:db2e:c:/data/"; //移动数据库的位置在 c:/data/
try {
Connection con = null;
DB2eDataSource ds = new DB2eDataSource();
ds.setUrl(url);
con = ds.getConnection(); //建立移动数据库连接
Statement st = con.createStatement(); //创建statement句柄
st.executeUpdate("INSERT INTO stbl VALUES (1,'John')"); //执行插入语句
ResultSet rs = st.executeQuery("SELECT * FROM stbl");//执行查询语句
System.out.println("*** Query results:");
while (rs.next()) { //遍历结果集取得所有的行和列
System.out.print("idx=" + rs.getString(1) + ", ");
System.out.println("strdesc=" + rs.getString(2));
}//end while
rs.close();
st.close();
con.close(); //断开数据库连接
} catch (Exception ex) {
System.out.println(ex.toString());
}
}// end runSQL
public static void main (String[] args)
{
JdbcMain jmain = new JdbcMain();
jmain.runSQL();
}
}
|
在 Symbian 设备上运行应用程序
本文假定你已经安装了 Nokia PC suite,它可以通过 USB 接口连接 Symbian。本文选定 Nokia 9500 作为目标设备来运行应用程序。此外,确保在 N9500 上已经安装了合适的 JVM,比如 IBM 的用于 Symbian 的 J9。
考虑到 JVM 的向后兼容性,用清单 7 的脚本来编译源文件。
清单 7. 编译脚本
javac -target 1.1 -source 1.2 -classpath “isync4j.jar” SyncListener.java
javac -target 1.1 -source 1.2 -classpath “./;isync4j.jar” SyncMain.java
javac -target 1.1 -source 1.2 -classpath “jdbc.jar;db2ejdbc.jar” JdbcMain.java
|
在 N9500 设备的根目录 C 盘下,创建一个目录 MyApp,拷贝清单 8 中的文件到 MyApp 目录下。
清单 8. 需要拷贝到设备的文件列表
SyncListener.class
SyncMain.class
JdbcMain.class
db2sync_db2e.properties
runSQL.j9 and runSync.j9
isync4j.dll for the Symbian 7s
DB2EJDBC.dll for the Symbian 7s
|
清单 9 和清单 10 所示的是 runSync.j9 和 runSQL.j9 的内容。
清单 9. runSync.j9 的快捷方式
-noverify -Dcom.ibm.oti.vm.bootstrap.library.path=C:\MyApp
-Xbootclasspath/a:c:\System\java\ext\db2ejdbc.jar;
c:\System\java\ext\jdbc.jar;c:\System\java\ext\isync4j.jar;
c:\MyApp -Xmx16m -verbose:sizes SyncMain db2sync_db2e
|
清单 10. runSQL.j9 的快捷方式
-noverify -Dcom.ibm.oti.vm.bootstrap.library.path=C:\MyApp
-Xbootclasspath/a:c:\System\java\ext\db2ejdbc.jar;
c:\System\java\ext\jdbc.jar;c:\System\java\ext\isync4j.jar;
c:\MyApp -Xmx16m -verbose:sizes JdbcMain
|
现在可以运行应用程序 SyncMain 和 JdbcMain。
- 运行应用程序 SyncMain。
点击 runSync.j9 的快捷方式,它会启动 SyncMain 应用程序触发与 Sync Server 的同步。直到表 stbl 已经完全同步到设备上来。你可以可以通过目录 Communicator\logs\j9vm\ 下面的日志文件 stderr.txt 和 stdout.txt 看到输出的数据。
- 运行应用程序 JdbcMain。
点击 runSQL.j9 的快捷方式,它会插入一条记录到表 stbl 中,并且通过执行一条查询语句得到表 stbl 的所有记录。同时,你可以可以通过目录 Communicator\logs\j9vm\ 下面的日志文件 stderr.txt 和 stdout.txt 看到输出的数据。
总结
事实上,搭建开发环境、开发和运行 Symbian 平台上的 DB2 Everyplace 的 Java 应用是比较简单的步骤。通过全文的介绍,现在你已经知道如何用 sync API 来开发同步应用以及用 JDBC 接口开发 DB2 Everyplace 数据引擎之上的移动数据库应用。所以,接下来你可以更加深入地去尝试 DB2 Everyplace 的高级特性的应用开发。
参考资料 学习
获得产品和技术
讨论
作者简介  | |  | 王飞鹏是 IBM 中国软件开发中心的软件工程师。 |
 | |  | 王雪飞是 IBM 中国软件开发中心的高级软件工程师。 |
 | |  | 肖静静是 IBM 中国软件开发中心的软件工程师。 |
对本文的评价
|