先介绍一下BEA的DSP,所谓DSP就是data service platform,是BEA近几年推出的一个新产品,跟SOA架构有很紧密的联系,说简单点就是SOA的获取数据的那一层,这一层负责收集数据、整理数据并对外发布接口。
关于DSP其实BEA的DEV2DEV上有一个比较好的例子,但它的例子是基于weblogic自带的pointbase内存数据库为基础的,而实际中的数据源基本不可能使用pointbase,于是我个人最近两天做了一个基于mysql的demo,更贴近实际一点。
下面就来就一步一步介绍创建和部署这个demo。
顺便说一句,运行dsp至少要512M内存,推荐1G以上。
mysql的准备工作,新建一个schema名字叫VLS,然后新建几张表:
emailTemplate(emailTemplateID int(PK), emailTemplateName varchar)
emailTemplatePack(emailTemplatePackID int(PK), emailTemplatePackName varchar)
emailTemplateBridge(emailTemplateID int, emailTemplatePackID int)
其中emailTemplate就是一个邮件的内容定义,emailTemplatePack就是定义一组邮件,在我的项目中就是定义一个课程全过程中的邮件,包括课程创建提醒,课程确认,课程时间提醒1、2、3之类的,emailTemplateBridge是定义两张表的多对多的关系。两个ID都是FK。数据自己随便输点。
下载bea weblogic 8.1.6 platform并安装到默认目录。
下载data service platform并安装,目前的版本是2.5。
这两个下载的地址在[url=http://dev2dev.bea.com]http://dev2dev.bea.com[/url] 自己去找吧。
下载mysql的driver,并复制到C:/bea/weblogic81/server/lib中。这步是一定要有的,很奇怪的是BEA并没有在自己的lib目录里面附带对应数据库的driver文件,或许是我没有找到。
设置环境变量,修改C:/bea/weblogic81/common/bin/commEnv.cmd,找到这句设置WEBLOGIC_CLASSPATH的环境变量
set WEBLOGIC_CLASSPATH=%JAVA_HOME%/lib/tools.jar;%WL_HOME%/server/lib/weblogic_sp.jar;
在后面加上%WL_HOME%/server/lib/weblogic.jar;%WL_HOME%/server/lib/mysql-connector-java-3.0.15-ga-bin.jar
(我下载的mysql driver是mysql-connector-java-3.0.15-ga-bin.jar),当然,你可以把这个driver放到其他classpath中。
保存并关闭文件。
打开bea workshop,新建一个data service application,使用默认的weblogic server,名字叫VLS,我是根据我手上的一个项目来作例子,名字也就使用原来项目的名字了。建好以后,会自动建一个dataservices的项目。
一般情况下可以使用这个默认的ds项目,但个人更喜欢建一个新的项目。鼠标右键点击VLS也就是最顶层的application,弹出菜单中有一个new,二级菜单中单击project,弹出菜单如图。
修改名字为EmailTemplate,这个DS项目依照VLS项目中的邮件功能部分作为原型。
右键EmailTemplate这个DS项目然后新建两个文件夹,一个叫DS,一个叫Model。建好以后的项目结构图如下:
右键DS这个文件夹,然后选择Import Source Meta这个项目。如图:
点击后弹出的页面如图:
点next按钮,如果在开始没有启动weblogic server,这个时候会弹出一个对话框让你启动weblogic server,点确定就可以了。这个时候就会启动server,过程比较长,慢慢等吧。
当弹出的dos窗口中出现这样的文字
server started in running mode的时候,server就启动成功了。
下一个页面就是选择你要import的data source,默认的一般是pointbase自带的cgDataSource这个pool
点击页面上的new按钮,会弹出data source viewer来查看现有的已经配置好的data source pool和pool中的data source
点击当前页面的左下角的New data source按钮,弹出一个新建data source的对话框
在Pool的下拉菜单中选择<Create new pool>来新建一个pool,然后下面的这些Pool Name, Driver等就会被激活,可以进行修改,在Driver下面选择com.mysql.jdbc.Driver这个,然后URL就会出现一个template: jdbc:mysql://<localhost>:3306/<databasename>,把IP地址和数据库名字填写好以后就可以使用了。
新建好以后,就可以在第一个select data source中选择刚刚建立好的data source了。
data service分成两种,一种是物理意义上的数据服务,就像email template这种直接从数据库获取数据的服务。还有一种是逻辑服务。我们接下来作的就是根据物理数据服务定制自己想要的逻辑服务。
在model文件夹里新建一个Model Diagram,名字叫EmailTemplate.md
然后把emailTemplate那三个DS都拖入到这个model diagram里面来,就可以一次性看到三者的关系
右键EmailTemplate,然后新建一个DS,名字叫emailTemplateList
右键空白区域,选择Create xml type,会弹出一个菜单,点击create就可以。然后弹出一个对话框:
如果emailTemplateList.xsd不在schemas文件夹里,就把它拖进去。
双击emailTempalteList.ds,里面只有一个root元素emailTemplateList,需要我们自己来修改xsd文件从而来获得想要的数据格式。
右键点击emailTemplate这个根元素,然后选择Add Child--->Element,这样添加三个element,分别是emailTemplatePackID和emailTemplatePackName还有emailTemplateList,然后右键点击emailTemplateList再以它为父结点加入几个新element,这些element名字可以参考emailTemplate的定义。简单一点就直接把emailTemplate下面的东西复制过去。
这样新建好的emailTemplateList.ds就是这个样子的
而emailTemplateList.xsd的内容如下:
<xs:schema targetNamespace="ld:EmailTemplate/emailtemplatelist" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="emailtemplatelist">
<xs:complexType>
<xs:sequence>
<xs:element name="emailTemplatePackID"/>
<xs:element name="emailTemplatePackName"/>
<xs:element name="EmailTemplateList">
<xs:complexType>
<xs:sequence>
<xs:element name="emailTemplate" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="emailTemplateID" type="xs:int"/>
<xs:element name="emailTemplateTriggerName" type="xs:string" minOccurs="0"/>
<xs:element name="emailTemplateSendMode" type="xs:int"/>
<xs:element name="emailTemplateSubject" type="xs:string" minOccurs="0"/>
<xs:element name="emailTemplateText" type="xs:string" minOccurs="0"/>
<xs:element name="emailTemplateDaysThreshold" type="xs:int" minOccurs="0"/>
<xs:element name="emailTemplateCCAddress" type="xs:string" minOccurs="0"/>
<xs:element name="emailTemplateBCCAddress" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
还记得如何建一个新的函数吧,不记得了就看上面的步骤,在emailTemplateList.ds里新建一个函数名叫getEmailTemplatePack,这次我们要不光返回一个emailTemplatePack,还要把它所有包含的emailTemplate全部返回。
建好函数以后,单击函数,进入XQuery Editor View,最原始的是只有return
接下来几步是拖动DS到这个editor里。
先把emailTemplatePack里的emailTemplatePack()函数拖入到这个窗口里面,然后把emailTemplatePackID和emailTemplatePackName对应。记得是从For往return里面拖。
然后把emailTemplate这个DS里的emailTemplate()函数拖入这个窗口里面,把emailTemplate里面的元素一一对应
最后把emailTemplateBridge的emailTemplateBridge()拖入窗口里。
把emailTemplateBridge/emailTemplatePackID和return 里面的emailTemplatePackID对应。
把emailTemplatePack/emailTemplatePackID和emailTemplateBridge/emailTemplatePackID对应
把emailTemplateBridge/emailTemplateID和emailTemplate/emailTemplateID对应。
这几个步骤可能比较烦,细心点。然后检查下源代码,代码应该跟下面的一样,不一样的可以自己手动修改一下
declare namespace ns16="ld:EmailTemplate/emailtemplate";
declare namespace ns15="ld:EmailTemplate/emailtemplatepack";
import schema namespace ns11="ld:EmailTemplate/emailtemplatelist" at "ld:EmailTemplate/schemas/emailtemplatelist.xsd";
declare namespace ns14="ld:EmailTemplate/emailtemplatelist";
...
declare function ns14:getEmailTemplatePack() as element(ns11:emailtemplatelist)* {
for $emailtemplatepack in ns15:emailtemplatepack()
return
<ns11:emailtemplatelist>
<emailTemplatePackID>{fn:data($emailtemplatepack/emailTemplatePackID)}</emailTemplatePackID>
<emailTemplatePackName>{fn:data($emailtemplatepack/emailTemplatePackName)}</emailTemplatePackName>
<EmailTemplateList>
{
for $emailtemplatebridge in ns17:emailtemplatebridge()
where $emailtemplatepack/emailTemplatePackID = $emailtemplatebridge/emailTemplatePackID
for $emailtemplate in ns16:emailtemplate()
where $emailtemplatebridge/emailTemplateID = $emailtemplate/emailTemplateID
return
<emailTemplate?>
<emailTemplateID>{fn:data($emailtemplate/emailTemplateID)}</emailTemplateID>
<emailTemplateTriggerName?>{fn:data($emailtemplate/emailTemplateTriggerName)}</emailTemplateTriggerName>
<emailTemplateSendMode>{fn:data($emailtemplate/emailTemplateSendMode)}</emailTemplateSendMode>
<emailTemplateSubject?>{fn:data($emailtemplate/emailTemplateSubject)}</emailTemplateSubject>
<emailTemplateText?>{fn:data($emailtemplate/emailTemplateText)}</emailTemplateText>
<emailTemplateDaysThreshold?>{fn:data($emailtemplate/emailTemplateDaysThreshold)}</emailTemplateDaysThreshold>
<emailTemplateCCAddress?>{fn:data($emailtemplate/emailTemplateCCAddress)}</emailTemplateCCAddress>
<emailTemplateBCCAddress?>{fn:data($emailtemplate/emailTemplateBCCAddress)}</emailTemplateBCCAddress>
</emailTemplate>
}
</EmailTemplateList>
</ns11:emailtemplatelist>
这个是标准的XQuery的程序,前几步是声名namespace,函数里面首先对emailTemplatePack进行循环,在第二级对emailTemplateBridge进行循环,如果两个packID相等就得到emailTemplateID,然后循环完毕就组成一个新的xml文件。
修改好源代码后再返回xquery editor view,页面显示如下:
最后进入Test View,点击execute,显示结果,我的结果如下:
可以看到每个emailTemplatePack根据多对多的关系建立起一个email group
完