与后台数据库同步
类DBManager也允许应用程序开发者用PointBase 专有UniSync引擎与后台数据库同步移动数据。不同的厂商使用不同的同步引擎,但他们的概念都是相类似的。同步过程按照如下这些步骤进行:
1. 在后台服务器和移动设备上创建相应的数据库和表
2. 在同步服务器上创建一个hub。这个hub包含发布信息。它指定和标识用于同步(发布)的后台表(或部分表)。
3. 使用hub来创建spoke。spoke是在同步服务器上表示移动设备的对象。每个spoke都有一个ID。它能通过在同一个hub里的订阅对象来订阅发布。通过使用一个spokeID,移动设备匹配spoke并对订阅的后台表进行同步。
4. 启动同步服务器。基本上通过com.pointbase.me.sync.Server 类的main()方法来执行。这个服务器类用于PointBase 发布包。还有其他几个方法在不同环境中运行服务器。您可以参考PointBase文档来得到更多的细节和例子。默认情况下,服务器监听端口8124。
5. 使用一个spokeID和在移动设备上的类 spoke stub 来初始化同步过程。
 图3 UniSync同步服务器框架图解
例3 中的类ResetServer显示了在UniSync服务器上如何创建hub和spoke:
例3 安装同步服务器
manager=SyncManager.getInstance(caturl,catdriver,catuser,catpassword); String dsname; dsname=SyncDataSource.DEFAULT;
String hubname="Hub"; Hub hub=manager.createHub(hubname);
Publication pub; String pubname; SpokeConfig spoke; Subscription sub; String subname="SubNameCard"; String tablename="NAMECARD"; String[] tables=new String[]{tablename};
// Publish the complete name-card table pubname="PubNameCard"; pub=hub.newPublication(pubname,dsname,tables); hub.publish(pub);
// Create two spokes and subscribe to this publication for(int i=1;i<=2;i++) { String name="Spoke"+i; spoke=hub.createSpokeConfig(name); spoke.savePassword("pass"+i); sub=spoke.newSubscription(subname,SyncDataSource.DEFAULT,pubname); spoke.subscribe(sub); }
// Publish the name-card table without the picture column
pubname="PubNameCardNoPicture"; pub=hub.newPublication(pubname,dsname,tables); SyncTable table=pub.getSyncTable(tablename); table.dropSyncColumns(new String[]{"PICTURE"}); hub.publish(pub);
// Create two spokes and subscribe to this publication for(int i=3;i<=4;i++) { String name="Spoke"+i; spoke=hub.createSpokeConfig(name); spoke.savePassword("pass"+i); sub=spoke.newSubscription(subname,SyncDataSource.DEFAULT,pubname); spoke.subscribe(sub); } manager.close(); |
下面的DBManager代码片断显示了如何获得spoke stub 和如何在设备上处理同步。代码中的注释解释了应用程序的同步和独立版本的不同:
例4 通过同步服务器访问数据
// Import proprietary classes for sync import com.pointbase.me.jdbc.*;
class DBManager {
// In addition to JDBC connection variables, // we also need to define variables for sync // ... ... private Spoke spoke; private String spokename; private int spoke_id; private int spoke_range_start,spoke_range_end; final static int ROWS_PER_SPOKE=1<<16; private String syncurl; private String syncpassword;
private DBManager() {
// Get DB connection parameters // ... ...
// Get sync parameters syncurl = properties.getProperty("syncurl", "http://localhost:8124";); String spokeid = properties.getProperty("spokeid", "1"); spokename = properties.getProperty("spoke", "Spoke"+spokeid); syncpassword = properties.getProperty("syncpassword", "pass"+spokeid); url = properties.getProperty("url", "jdbc:pointbase:micro:pbdemo"+spokeid);
connect(); }
// The complete connect method using synchronization server private void connect() { try { System.out.println("Connecting to the database...");
Class.forName(driver);
// If the database doesn't exist, create a new database connection = DriverManager.getConnection(url, user, password); statement = connection.createStatement();
// Check sync metadata and create tables loadMeta();
// Create prepared statements createStatement();
} catch (Exception e) { e.printStackTrace(); System.exit(1); } }
// The complete newID method using the sync server private int getNewID() { try { ResultSet rs = statement.executeQuery( "SELECT MAX(ID)+1 FROM NameCard WHERE "+ "ID>="+spoke_range_start+" AND ID<"+spoke_range_end); rs.next(); int id=rs.getInt(1); if(rs.wasNull()) { return spoke_range_start; } else { return id; }
} catch (Exception e) { e.printStackTrace(); } return 0; }
// Create table and load metadata from the sync hub void loadMeta() { try { SyncManager manager=SyncManager.getInstance(connection); spoke=manager.getSpoke(spokename); if(spoke==null) { System.out.println( "Loading MetaData from url "+syncurl+ " for spoke "+spokename+ " using password "+syncpassword); spoke=manager.createSpoke(spokename); spoke.savePassword(syncpassword); spoke.saveHubURL(syncurl); spoke.loadConfig(); spoke.getSnapshot(); } spoke_id = spoke.getSpokeId(); System.out.println("SpokeID is "+spoke_id); spoke_range_start = ROWS_PER_SPOKE * spoke_id; spoke_range_end = spoke_range_start + ROWS_PER_SPOKE - 1; } catch (SyncException e) { e.printStackTrace(); } }
// Synchronize spoke databases (mobile databases) with the hub // and backend databases void sync() { try { spoke.sync(); } catch (SyncException e) { e.printStackTrace(); } }
// Other data access methods are the same as the non-synced version. } |
|