技术开发 频道

DdlUtils实现Mobile Client开发篇

【IT168 技术文档】摘要:本文在介绍DdlUtils应用的基础上,对数据库模型以及DdlUtils实现Mobile Client的开发过程进行了重点说明。通过对开发过程中的一些注意点进行补充说明,让开发人员对DdlUtils实现Mobile Client有一个更深入的理解。

1  引言

使用DdlUtils可以实现分布式数据处理和数据库转移等Mobile Client应该具备的应用特征。所有的应用框架大致为是:以关系型数据库为中心,在分布式的客户端进行离线数据处理,再通过DdlUtils包来实现客户端与数据中心的同步。

2  DdlUtils核心概念

这里笔者觉得有必要向读者详细介绍DdlUtils的两个核心概念:数据库模型(Database Model)和平台(Platform)。只有深入了解了这两个概念,我们才能大致明白DdlUtils的实现机制。

2.1  数据库模型

首先我们以一个实际的数据库模型定义文件为例(下图1):
 
图1:DdlUtils用到的数据库模型定义文件

读者可以不难地看出,DdlUtils把数据库以及其中数据表的定义统一抽取成DdlUtils所认可的模式。其中XML结点中database元素对应数据库,table元素对应数据库中数据表,column元素对应数据表中每一字段。数据库,数据表和字段都由名称标识。对于字段,还存在是否主键,类型和大小等定义。

我们暂且不考虑DdlUtils为什么要将数据库的模型按照这些元素进行定义,但是我们可以知道:通过这个模型定义文件,我们已经完全知道数据库,数据表以及各字段的定义信息。

2.2  平台

DdlUtils将平台(Platform)定义为封装了与数据库相关的诸如查询,数据维护等功能的层面。言下之意就是所有数据库,数据表和字段的操作都纳入了平台的范围。所以DdlUtils的平台可以理解为数据库相关的操作平台。

可能有读者要问:既然是与数据库相关,那么对于不同的关系型数据库(RDBMS),对应的平台是否也是不同的?答案是肯定的。DdlUtils从平台接口实现了很多与各种RDBMS相关的子平台,例如:FirebirdPlatform(Firebird DB),MySqlPlatform(MySQL DB),PostgreSqlPlatform(PostgreSQL DB)等等。甚至对同一RDBMS不同版本的产品,其子平台也是不相同的。例如对于Oracle数据库的不同版本存在3个子平台:Oracle10Platform,Oracle8Platform和Oracle9Platform。

3  Mobile Client的开发流程

Mobile Client的开发流程主要包括3个重要环节:数据库模型的导出,数据库数据的导出和数据文件的导入。

3.1  数据库模型的导出

从活动的数据库中导出数据库模型。数据库模型的导出必须要有数据源(DataSource),而数据源需要由活动的数据库的URL来建立。平台通过读取方法(readModelFromDatabase)直接从数据源中获取数据库模型,再通过数据库模型I/O类(DatabaseIO)的写出方法将模型转换成XML文件。

本案例中通过Apache DBCP(Database Connection Pool API)包,建立了基于连接池的数据源。以下是关键代码:

public DataSource setupDataSource() { //org.apache.commons.dbcp.BasicDataSource BasicDataSource bds = new BasicDataSource(); //Sets the jdbc driver class name. bds.setDriverClassName("com.mysql.jdbc.Driver"); //Sets the url. bds.setUrl("jdbc:mysql://localhost/phome"); //Sets the username. bds.setUsername("root"); //Sets the password. bds.setPassword(""); return bds; }

以下是数据库模型的输出关键代码,可以说是寥寥数语:

public ExportModel(final String __modelFile) { DataSource ds = setupDataSource(); //Creates a new platform for the specified database. Platform pf = PlatformFactory.createNewPlatformInstance(ds); //Reads the database model from the live database as specified by the data source set for this platform. Database db = pf.readModelFromDatabase("phome"); //Writes the database model to the specified file. new DatabaseIO().write(db, __modelFile); }

所输出的模型文件,就是上图1中看到的内容。

3.2  数据库数据的导出

用于将活动的数据库中的数据转移到XML文件中。数据的导出必须结合数据源和数据库模型来完成。

(1)首先是载入数据库模型文件(即3.1中输出XML文件)。
通过数据库模型I/O类的读取方法来读取模型文件。

public Database getModelFromFile(File __modelFile) throws DdlUtilsException { //Reads the database model contained in the specified file. return(new DatabaseIO().read(__modelFile) ); }

(2)建立数据输出流
将数据库数据输出流绑定到文件即可实现数据库数据到文件的输出。

(3)通过平台执行SQL语句,将数据集通过数据输出流写入到XML文件中。
需要注意的是:
①导出过程可以是条件导出,例如:只导出符合条件的记录,或者只导出指定的字段等等,通过SQL条件语句就可以实现,不需要开发人员关注导出过程。

②1个数据输出流对象可以用于输出1个数据库中所有的数据表。1个数据输出流对象只能对应1个数据库。对于多个数据库,就需要建立多个数据输出流对象。以下是关键代码:

以上代码中,通过1个数据输出流对象和多个SQL语句实现了同一数据库中多个数据表的数据输出。下图2是一个实际的数据库导出文件:
 
图2:数据库导出文件
 

3.3  数据文件的导入

用于将数据从XML文件导入到活动的数据库中。对于导入过程可以是批量导入也可以是逐条插入方式。

对于批量导入,会将XML文件中所有的字段数据都将导入到数据库中。而采取逐条插入的方式可以条件地插入指定的字段。同样,整个导入过程不需要开发人员关注,全部由DdlUtils完成。

数据的导入必须结合数据库模型和数据文件和数据源来完成。以下代码中,通过数据接收器(sink)对数据文件中的数据进行了批量导入:
(1)通过数据库模型创建数据接收器(DataToDatabaseSink)
(2)通过指定数据读取对象(DataReader)的数据接收器(setSink),实现数据文件的批量读取(DataReader对象的parse方法)

需要说明的是:通过数据库数据I/O类(DatabaseDataIO)的写入方法(writeDataToDatabase)也可以实现将数据批量写入到数据库中,但是经过试验和分析,摸索出采用数据接收器的方式来进行批量插入,大大避免了与数据的“直接接触”,极大简化了处理过程。

以下是关键代码:

DataSource ds = setupDataSource(); //Creates a new platform for the specified database. Platform pf = PlatformFactory.createNewPlatformInstance(ds); //Creates a new sink instance. DataToDatabaseSink dtds = new DataToDatabaseSink(pf, __db); DataReader dr = new DataReader(); //Sets the database model. dr.setModel(__db); //Sets the data sink. dr.setSink(dtds); //Sets the (maximum) number of beans to insert in one batch. dtds.setBatchSize(64); //Notifies the sink that beans will be added. dtds.start(); //Parse the content of the specified file using this Digester. //Returns the root element from the object stack (if any). dr.parse(__dataFile); //Notifies the sink that all beans have been added. dtds.end();

4  结束语

不超过100行的代码,就实现了数据库模型的提取,数据库数据的导出和数据文件的导入。特别的是,用户甚至都不用知道数据库中数据的结构和内容。无论从工程的可维护性还是稳定性和执行效率却都是令人相当满意。

特别是数据文件的导入中,采用了笔者自己摸索出来的数据接收器的方式,极大简化了数据的批量导入。该环节对于缩短客户端与数据库中心的交互时间是相当有效的。

但是,要实现客户端与数据库中心同步,就可能会遇到插入冲突的问题。即:如果客户端的数据与数据库中心的数据存在重复,那么在客户端数据导入到数据库中心的过程中就会发生异常。这个时候就可能不得不通过冲突检测来进行非批量的插入。虽然关于DdlUtils带有冲突检测的批量导入还在评价之中,但是无庸置疑的是:这样势必大大降低客户端与数据库中心同步的效率。

基于这一点考虑,通过一定的业务规定来避免客户端的数据与数据库中心产生冲突,也未尝不是一个高效的做法。

0
相关文章