不少系统中都有动态数据表的存在比如按日或者按月在数据库中生成一个表以日表为例其表名的形式为TableName_XXXX_XX_XX如TableName___等表明其表内数据存放的是年月日所产生的数据在这些日表中表结构完全相同只是在表名上有所区别
而在ALDSP从关系数据库中导入元数据(import Meta Data)时无论是直接从表导入还是从SQL语句导入都必须提供其表名否则无法生成Data Services但是在不少客户的应用中经常是要根据选择的时间范围来动态的查询一个表或者多个表根据客户提出的这些要求经过研究发现在ALDSP中要比较方便的解决这个问题主要可以通过两个途径解决其一是在数据库端生成一个函数(function)或者存储过程(store procedure)设定表名作为参数然后由ALDSP导入生成Data Services其二是直接利用ALDSP可以从函数导入元数据的功能先生成一个以表名为参数的函数然后导入ALDSP生成Data Services
以下主要介绍第二种方法的实现
在ALDSP中可以从多种异构数据源中取得数据包括数据库flatfilexml文件Web ServicesJava函数等从Java函数中生成Data Services有几点要注意的地方详见其中包括函数的定义必须为static还有就是返回值有些限制主要可以返回两种类型其一为Java原始类型(primitive types)或者原始类型的数组其二为复杂类型(complex types)或者复杂类型的数组在一般的Java程序中返回复杂类型数据一般会用到JavaBean或者JavaBean的数组或者直接用一个容器返回但是对ALDSP而言无论是容器或者JavaBean的数据ALDSP均不能从中获取到所需的元数据(Meta Data)信息要满足ALDSP元数据获取的要求我们可以通过一个JavatoXML或者JavaBena的技术来对其返回值进行封装
针对以上这些情况我们通过一个模拟的例子来实现这个解决方案首先在数据库中生成两张表表名为table和table结构如下
字段名 | 类型 | ID字符串型NAME字符串型
根据表的类型设计XMLBean的XML Schema来适应我们的需要
以下为图形化视图(由XMLSPY生成)
XML文件源代码如下
<?xml version=?> <xsschema xmlnsxs= xmlnstns= targetNamespace= elementFormDefault=qualified attributeFormDefault=unqualified> <xselement name=AllUser> <xscomplexType> <xssequence> <xselement name=User minOccurs= maxOccurs=unbounded> <xscomplexType> <xssequence> <xselement name=ID type=xsstring/> <xselement name=Name type=xsstring/> </xssequence> </xscomplexType> </xselement> </xssequence> </xscomplexType> </xselement> </xsschema>然在在Workshop里新建一个应用程序再新建一个Schema Project再新建一个XML Schema如下所示
保存AllUserxsd后会自动编译成生XMLBean的包
这样我们就可以在定义的Java类中返回XMLBean类型的数据了
接下来在当前应用程序中新建一个Java工程加一个Java类生成一个类如下
import javasqlConnectionimport javasqlDriverimport javasqlResultSetimport javasqlStatementimport javautilHashtableimport javaxnamingContextimport javaxnamingInitialContextimport javaxsqlDataSourceimport orgopenuritemptestDynamicTableallUserAllUserDocument
public class DynamicTable { //函数的函数为表名public static AllUserDocument getUser(String tablename)
{ AllUserDocument docAllUserDocumentAllUser alluserAllUserDocumentAllUserUser user//先生成一个XMLBean的实例doc = AllUserDocumentFactorynewInstance()//像这个实例中加入一个节点alluser = docaddNewAllUser()try { Hashtable env = new Hashtable()Context ctx = nullctx = new InitialContext()DataSource ds = (DataSource)ctxlookup(cgDataSource)Connection conn = dsgetConnection()Statement stmt = conncreateStatement()ResultSet rs = stmtexecuteQuery(select idname from +tablename)//通过JDBC取得数据集ResultSet while(rsnext())
{ //然后将数据集中的数据加入到XMLBean中user = alluseraddNewUser()usersetID(rsgetString(id))usersetName(rsgetString(name))} Systemoutprintln(doctoString())} catch(Exception ex)
{ exprintStackTrace()} //将结果集包装为XMLBean后返回return doc}以上代码的主要原理是通过JNDI取得数据源然后使用根据传入的表名拼装出一个SQL查询语句然后由取得结果集后生成XMLBean返回
经过编译后就可以导入生成一个Data Services了
最后测试结果如下
后记
ALDSP的功能很强大现在也有越来越多的关键应用在通过ALDSP来实现特别是异构数据源的访问多数据库的集成等业务而在ALDSP中通过导入Java函数做为数据源则更是进一步的模糊了数据源这个传统概念的边界总的来说通过Java函数ALSDP可以很灵活的处理各种数据结构比如将数据库与LDAP Server的数据放在在一起访问通过Java函数ALDSP可以与任何一种能由Java处理的数据进行集成从而得到统一数据访问的目的ALDSP的这些功能对于SOA下各种异构数据的统一处理尤为重要