UML软件工程组织

 

 

从数据库调用 WebSphere 业务流程
 
作者:Robert Peterson (rrpeters@us.ibm.com), 德克萨斯州奥斯汀的 WebSphere 支持   来源:IBM  
 

本文内容包括:

大型企业的大多数业务事务都保留在数据库中。在本文中,最资深的 IBM WebSphere 顾问之一展示了如何使用 WebSphere Integration Developer、WebSphere Process Server、DB2 和 WebSphere Adapter for JDBC,从而利用数据库事件来调用业务流程。

 引言

本文将开发一个客户订单示例应用程序,它使用 IBM? WebSphere? Integration Developer、WebSphere Process Server、DB2? 和 WebSphere Adapter for JDBC,以利用数据库事件来调用业务流程。了解数据库驱动的业务流程如何能够帮助您加快上市时间和降低总体拥有成本。

先决条件

为了开发这个循序渐进的示例应用程序,应考虑下列先决条件:

  • WebSphere Integration Developer。您将同时需要开发环境和 WebSphere Process Server 集成测试环境,后者是开发环境安装过程中的一个选项。该集成测试环境包括完整的 WebSphere Process Server 运行时,我们将使用它来测试本文中的示例。
重要:如果您是大学生或在学术机构工作,可以通过加入 IBM 教育学院教育培养计划来下载 WebSphere Software 系列的子集:http://www-304.ibm.com/jct09002c/university/scholars/
  • WebSphere Adapter for JDBC。 请参见参考资料以获得官方 WebSphere Adapter for JDBC IBM 网站地址。
  • DB2 Universal Database V8.2。该示例使用 DB2;不过,可以使用任何兼容 JDBC 的数据库,只要您习惯使用它来创建触发器并熟悉其 JDBC 驱动程序。下面的站点提供了 DB2 Universal Database V8.2.2 的试用版:
    http://www14.software.ibm.com/webapp/download/brand.jsp?b=Information%20Management&dt=Trial

WebSphere JCA 1.5 适配器

Java? Component Architecture (JCA) 是 Java Enterprise Edition (Java EE) 规范的一部分,用于提供一种标准方法来与非 Java EE 系统进行事务通信,如图 1 所示。WebSphere 系列提供了一组适配器来连接到各种企业信息系统 (Enterprise Information Systems, EIS),如 SAP 和 Peoplesoft。

图 1. 将 EIS 与 JCA 适配器集成
 
 本文将利用 WebSphere Adapter for Java Database Connectivity (JDBC),它能与任何具有兼容 JDBC 驱动程序的数据库集成。当数据库表中发生创建、更新或删除事件时,我们将使用该适配器的“入站接口”来调用业务流程。有关 Java Connector Architecture 和 WebSphere 适配器组合的更多信息,请参见参考资料。

数据库驱动的业务流程的业务案例

您的组织的后端基础设施可能很适合对业务流程进行数据库驱动的调用,但是该体系结构设计决策并不是完美无瑕的。请从业务角度考虑下列因素:

  • 遗留环境中的数据库驱动的业务流程。如果您有遗留系统,并且它们已经提供了信息来调用数据库中的业务流程,则数据库驱动的业务流程可能是加快上市时间的关键。数据库可以充当调用企业体系结构中的业务流程的自然实体,对于遗留集成尤其如此,因为组织通常已经有与他们在数据库中的业务流程相关的事务。
  • 事务服务质量。如果您处在不能承受任何一个事务失败的环境中——如开发票、交易或报价——则结合使用 WebSphere Adapter for JDBC 和成熟的数据库系统可以提供所需的服务质量。JCA 规范的一个重要优点在于,它定义了 Java EE 适配器将如何成为事务性的,以使它们能够参与 Java EE 容器事务。因此,WebSphere Adapter for JDBC 可以与您的业务流程一起参与全局事务。如果某个业务流程失败,则会回滚该全局事务,包括适配器已在该事务期间执行的任何数据库交互。
  • 数据库技能“比比皆是”。利用现有的数据库事件来调用业务流程可以降低总体拥有成本,因为组织中可能已经拥有开发和管理数据库事件的技能。对于许多使用数据库驱动的业务流程的组织来说,建立必要的数据库触发器和数据库交互构件是非常直观的。然而,如果您的组织刚开始使用 WebSphere Integration Developer、服务组件体系结构 (Service Component Architecture, SCA) 和 BPEL 业务流程,则可能需要大量的强化培训来构建业务流程本身。有关这些技术的更多信息,请参见参考资料。
  • 性能不是该体系结构的强项。网络和数据库访问的开销非常大,因此,如果吞吐量极为重要,则这可能无法满足您的需要。例如,如果另一个系统 System A 编写了一个数据库事件,然后 WebSphere Process Server 选择它来调用某个业务流程,则该数据库实质上是“中间人”。消除了中间数据库的任何体系结构将具有更多的性能潜力。例如,如果 System A 支持 JMS、MQ、RMI 或 Web 服务,它就可以直接与 WebSphere Process Server 通信。此外,如果 System A 由另一个 WebSphere 适配器(如 Siebel 或 Oracle 适配器)支持,则这样的适配器更为合适,因为它也消除了中间的数据库。

总之,对于遗留集成、事务服务质量和以数据库或大型机为中心的技能集而言,数据库驱动的业务流程是强有力的体系结构设计决策。当存在严格的性能要求或存在开销很大的网络延迟时,数据库驱动的业务流程可能不是最佳的解决方案。

客户订单示例

本部分将详细描述该客户订单示例应用程序的配置和开发。该示例应用程序由接受客户订单的业务流程组成。请考虑下列数据库实体:

图 2. 订单应用程序数据库实体

 在对 ORDER 表创建、更新或删除一个行时,将会通过对应的数据库触发器向 ORDER_EVENT 表添加一个行。JCA Adapter for JDBC 利用 ORDER_EVENT 表来调用下游业务流程,如图 3 所示。该适配器是通过轮询 ORDER_EVENT 表中的新行(以您可以指定的间隔)来实现这点的。

图 3. 订单应用程序概述

上图是与供应商无关的通用图解。对于我们的示例应用程序,左侧的数据库为 DB2,Java EE 运行时为 WebSphere Process Server,业务流程为使用 WebSphere Integration Developer 来开发的基于业务流程执行语言(Business Process Execution Language,BPEL)标准的服务组件体系结构 (SCA) 业务流程组件。

 创建 DB2 表和触发器

下面的说明逐步地为该客户订单示例完成新的 DB2 数据库以及必要的表和触发器的创建。

  1. 启动 DB2 命令中心。我们将在该示例的开发过程中广泛地使用 DB2 命令中心。如果您更喜欢使用 DDL 脚本来建立数据库,请参见下载部分,其中包括 db2-order-tables-and-triggers.ddl。
    1. Windows
      若要在 Windows 下启动命令中心,请打开“开始”菜单中的“程序”,然后选择 IBM DB2 => Administration => Command Center。
    2. Linux
      在 Linux 下,您需要以 DB2 管理用户身份来执行 db2cc 脚本。下面是一个示例:

      清单 1. 在 Linux 下启动 DB2 命令中心
      [rain%] su db2admin
      [rain%] password: ********
      [rain%] /opt/IBM/db2/V8.2/bin/db2cc
  2. 打开命令中心以后,创建一个名为 ORDERS 的新数据库。为此,请右键单击 Databases 并选择 Create Database => Standard ,然后再选择 Finish。
    图 4. 创建 ORDERS 数据库 创建
  3. ORDERS 数据库以后,通过选择“c:>”图标来打开命令编辑器。

    图 5. 打开命令编辑器
  4. 单击 Add 将命令编辑器连接到 ORDERS 数据库。取消选中 Use implicit credentials 并插入您的 DB2 实例的用户名和密码。

    图 6. 将命令编辑器连接到 ORDERS 数据库

    重要:本文假设数据库模式的名称为 db2admin。务必要注意这一点,因为我们为 WebSphere Process Server 开发的构件将作为它们的命名约定的一部分包括该模式名称。如果您在缺省情况下没有该模式,则建议您使用下面的命令创建一个名为 db2admin 的模式,以便完成这个逐步示例而无需不必要的调试。

    清单 2. 创建 db2admin 模式
    CREATE SCHEMA db2admin AUTHORIZATION <your-admin-username-here>

  5. 在命令编辑器中插入下面的命令并单击执行按钮,如图 7 所示。

    清单 3. 创建 Order 表
    CREATE TABLE ORDER (
    ORDER_ID INTEGER NOT NULL PRIMARY KEY,
    DESC VARCHAR(255),
    QTY INTEGER,
    );

    图 7. 创建 ORDER 表

  6. 类似地,输入下面的命令来创建订单事件表和触发器,以填充针对插入、更新和删除操作的事件表。

    重要:如果您希望监视的是现有表而不是 ORDER 表,则可以使用同一个事件表。如果要使用不同的模式名称,您需要更改所有三个触发器,以插入不同的 OBJECT_NAME。所插入的文本必须与适配器使用的业务图名称准确匹配(请参见创建业务流程的步骤 2)。该文本的格式为 <schema-name><table-name>BG。例如,如果您的模式名称为 AS2,要监视的表名为 PROCUREMENT,则将所有 Db2adminOrderBG 引用更改为 As2ProcurementBG

    清单 4. 创建事件表和触发器
    CREATE TABLE ORDER_EVENT (
    EVENT_ID INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY
    (START WITH 1, INCREMENT BY 1, NO CACHE ) PRIMARY KEY,
    OBJECT_KEY INTEGER NOT NULL,
    OBJECT_NAME VARCHAR(40) NOT NULL,
    OBJECT_FUNCTION VARCHAR(40) NOT NULL,
    EVENT_PRIORITY INT NOT NULL,
    EVENT_TIME TIMESTAMP DEFAULT CURRENT TIMESTAMP NOT NULL,
    EVENT_STATUS INT NOT NULL,
    EVENT_COMMENT VARCHAR(100)
    );

    CREATE TRIGGER event_create
    AFTER INSERT ON ORDER REFERENCING NEW AS N
    FOR EACH ROW MODE DB2SQLINSERT
    INTO ORDER_EVENT
    (object_key, object_name, object_function, event_priority, event_status)
    VALUES
    (N.ORDER_ID, 'Db2adminOrderBG', 'Create', 1, 0);

    CREATE TRIGGER event_update
    AFTER UPDATE ON ORDER REFERENCING NEW AS N
    FOR EACH ROW MODE DB2SQLINSERT
    INTO ORDER_EVENT
    (object_key, object_name, object_function, event_priority, event_status)
    VALUES
    (N.ORDER_ID, 'Db2adminOrderBG', 'Update', 1, 0);

    CREATE TRIGGER event_delete
    AFTER DELETE ON ORDER REFERENCING OLD AS O
    FOR EACH ROW MODE DB2SQLINSERT
    INTO ORDER_EVENT
    (object_key, object_name, object_function, event_priority, event_status)
    VALUES
    (O.ORDER_ID, 'Db2adminOrderBG', 'Delete', 1, 0);
  7. 我们需要在 WebSphere Process Server 的库目录中包括必要的 DB2 JDBC Type 4 驱动程序和许可证 JAR。缺省情况下,您需要复制的文件位于下列位置:
    1. Linux
      /home/db2inst1/sqllib/java/db2jcc.jar
      /home/db2inst1/sqllib/java/db2jcc_license_cu.jar
    2. Windows
      C:\Program Files\IBM\SQLLIB\java\db2jcc.jar
      C:\Program Files\IBM\SQLLIB\java\db2jcc_license_cu.jar
  8. 将两个 JAR 都复制到 WebSphere Process Server 安装的 lib 目录。假设您使用被用作 WebSphere Integration Developer 的集成测试环境的 WebSphere Process Server 运行时,则库目录的缺省位置如下:
    1. Linux
      /opt/ibm/WebSphere/ID/runtimes/bi_v6/lib
    2. Windows
      C:\Program Files\IBM\WebSphere\ID\runtimes\bi_v6\lib

导入和配置适配器

本部分将逐步地将 WebSphere Adapter for JDBC 导入您的 WebSphere Integration Developer 工作区并对其进行配置。

  1. 在新工作区中打开 WebSphere Integration Developer。
  2. 选择 File => New => Enterprise Service Discovery。这将调出一个向导,指导我们完成必要工作区构件的生成和数据库连接属性的配置。
  3. 单击 Import Resource Adapter 然后单击 Browse 按钮。从下面的位置选择 CWYBC_JDBC.rar:
    <your-adapter-install-directory>/adapter/jdbc/deploy

    图 8. 导入适配器资源
    重要:*.rar 文件是资源存档(类似于 *.war 或 Web 存档)。因此,CWYBC_JDBC.rar 是按照 Sun 的 JCA 规范来打包的 JCA 适配器本身。
  4. 此时会出现一个窗口,询问您是否希望切换到 J2EE 透视图。单击 Yes,然后选择 Enterprise Service Discovery 窗口。该适配器已作为一个 J2EE“Connector”项目导入到我们的工作区中。我们需要切换到 J2EE 透视图,以将 DB2 JDBC 驱动程序添加到 JDBC Adapter 项目的类路径中。
  5. 展开 Connector Projects 并右键单击 CWYPC_JDBC。然后选择 Properties => Java Build Path => Libraries 选项卡。单击 Add External JARs 并同时导入 db2cc.jar 和 db2jcc_license_cu.jar,如图 9 所示。

    图 9. 将 DB2 JDBC Type 4 驱动程序 JAR 添加到 Connector 项目
  6. 单击 OK,并通过选择右上角“J2EE”旁边的“打开透视图”图标来返回到 business integration 透视图。
  7. 通过单击 File => New 来再次打开 Enterprise Discovery Service 向导。选择 JDBC EMD Adapter 并单击 Next。

    图 10. Enterprise Service Discovery 向导
  8. 填写数据库凭据和连接属性,如图 11 所示。确保将 192.168.0.100 更改为承载 DB2 的计算机的“IP 地址”。如果 DB2 与 WebSphere Process Server 在同一台计算机上,您可以使用 localhost。如果您的 DB2 实例不使用缺省 50000 端口,则不要忘了还要更改该端口。

    图 11. 数据库凭据
  9. 单击 Run Query,您应该看到 db2schema 中的表,如图 12 所示。选择 ORDER 表,然后单击 => Add。最后,请单击 Next。

    图 12. 内省 ORDER 表

  10. 确保将 Service Type 设置为 Inbound,并对 BOLocation 插入 com/ibm/dataobjects。您可以将此视为适配器构件的包名称或名称空间。

    图 13. 选择 Inbound 服务类型

  11. 请注意,需要一个业务集成模块项目来存放适配器构件。请单击 New => Next 来创建一个这样的项目。对模块名称插入 EventDrivenProcess 并单击 Finish。

    图 14. 创建集成模块项目

  12. 选择 Use discovered connection properties,如图 15 所示。

    图 15. 数据库连接属性

  13. 该对话框将展开更多字段。请插入下面的信息:

    清单 5. 数据库连接属性
    Username: db2admin
    Password: <your-db2-password>
    EventOrderBy: EVENT_ID
    EventTableName: ORDER_EVENT
    DatabaseVendor: DB2

最后单击 Finish,您应该看到新创建的业务集成模块,它带有入站适配器 Export SCA 组件。

 创建业务流程

您的工作区现在看起来应该类似于图 16。当某个数据库事件发生时,将会调用 JDBCInboundInterface 组件。在本部分中,我们将构建在 JDBCInboundInterface 被调用时接收通知的组件。也就是三个调用来进行创建、更新和删除操作的业务流程。这里假设您熟悉服务组件体系结构 (SCA) 和 WebSphere 业务流程。有关使用 WebSphere Integration Developer 来开发业务流程的信息,请参见参考资料部分提供的信息中心。

图 16. 业务集成模块
 

  1. 我们的第一个步骤是创建一个使用订单创建事件的业务流程。右键单击 Interfaces 并选择 New => Interface。对名称插入 OrderCreate,对文件夹插入 com/ibm/interfaces。
  2. 创建一个与图 17 确切相似的界面。请注意,该操作名为 createDb2adminOrder,唯一的 Input 参数名为 Row,Row 的 BO 类型为 Db2adminOrderBG。此界面实际上是适配器界面的子集(仅包括创建操作)。

    图 17. 构建 OrderCreate 界面

  3. 在 com/ibm/interfaces 文件夹中创建另外两个分别名为 OrderUpdate 和 OrderDelete 的界面。创建与 OrderCreate 相同的 Input,只不过分别将操作命名为 updateDb2adminOrder 和 deleteDb2adminOrder。
  4. 右键单击组件编辑器的空白区域,然后单击 Add Node => Process。将其命名为 OrderCreateProcess。选择浮动的界面图标,并将其界面设置为 CreateOrder。双击 OrderCreateProcess 以实现该组件。对文件夹插入 com/ibm/interfaces。
  5. 在 Receive 组件下面,创建一个名为 LogProcessEntry 的 Java Snippet 组件。在 Properties 选项卡 => Details 下面为 LogProcessEntry 插入以下 Java 代码。实际上,您可能使用更高级的记录方法;不过这里为方便起见,我们将使用控制台。

    清单 6. OrderCreate LogProcessEntry 代码片段
    System.out.println(
    "============ New Order Process Invoked ============");
    System.out.println(
    "ORDER_ID is "+Row.getDataObject("Db2adminOrder").getInt("orderid"));
    System.out.println(
    "DESC is "+Row.getDataObject("Db2adminOrder").getString("desc"));
    System.out.println(
    "QTY is "+Row.getDataObject("Db2adminOrder").getInt("qty"));
    System.out.println(
    "===================================================");

  6. 下一步,创建一个名为 ApplyDiscountChoice 的 Choice 组件。为 Case 组件插入下面的 Java 代码:

    清单 7. ApplyDiscount Case 语句
    return Row.getDataObject("Db2adminOrder").getInt("qty") > 10;

  7. 在 Case 组件下面,创建另一个名为 Discount 的 Java Snippet。为 Discount 插入下面的 Java 代码:

    清单 8. Discount 代码片段
    System.out.println("++++++++ Discount Applied! ++++++++");

  8. 右键单击 ApplyDiscountChoice 组件并选择 Add Otherwise。在 Otherwise 组件下面,创建一个空组件并将其命名为 no-op。
  9. 结果 OrderCreateProcess 看起来应该与图 18 非常相似。您可能已经观察到了,此业务流程执行相关检查,以确定订单数量是否大于 10,并在情况属实时应用折扣。否则,它就正常处理该订单。在实践中,Discount 和 no-op 组件可能被替换为对订单处理 Web 服务、JMS 服务或其他 SCA 组件的调用。

    图 18. 订单创建业务流程

  10. 打开组装关系图并创建一个名为 OrderUpdateProcess 的业务流程。使用 OrderUpdate 界面并对文件夹使用 com/ibm/processes。与前面一样,添加一个名为 LogProcessEntry 的 Java Snippet,并使用下面的 Java 代码来填充它:

    清单 9. OrderUpdate LogProcessEntry 代码片段
    System.out.println(
    "============ Update Order Process Invoked ============");
    System.out.println(
    "ORDER_ID is "+Row.getDataObject("Db2adminOrder").getInt("orderid"));
    System.out.println(
    "DESC is "+Row.getDataObject("Db2adminOrder").getString("desc"));
    System.out.println(
    "QTY is "+Row.getDataObject("Db2adminOrder").getInt("qty"));
    System.out.println(
    "======================================================");
  11. 创建一个名为 CheckQuantityChoice 的 Choice 组件。使用下面的 Java 代码来填充 Case 组件:

    清单 10. CheckQuantity Case 语句
    return 0 == Row.getDataObject("Db2adminOrder").getInt("qty");
  12. 创建一个名为 RemoveOrder 的 Java Snippet。为 RemoveOrder 插入下面的 Java 代码:

    清单 11. RemoveOrder 代码片段
    System.out.println("++++++ QTY is 0. Removing Order. ++++++");
  13. 与前面一样,创建一个其下面带有 no-op 组件的 Otherwise 组件。
  14. 结果 UpdateOrderProcess 看起来应该与图 19 非常相似。该业务流程执行相关检查,以确定订单数量是否为 0。如果是,则从系统中删除该订单(同样,为简洁起见而只提供了实现存根)。

    图 19. 更新订单业务流程

  15. 创建一个名为 DeleteUpdateProcess 的业务流程。使用 OrderDelete 界面并对文件夹使用 com/ibm/processes。添加一个名为 LogProcessEntry 的 Java Snippet,并使用下面的 Java 代码来填充它:

    清单 12. OrderDelete LogProcessEntry 代码片段
    System.out.println(
    "============ Delete Order Process Invoked ============");
    System.out.println(
    "ORDER_ID is "+Row.getDataObject("Db2adminOrder").getInt("orderid"));
    System.out.println(
    "DESC is "+Row.getDataObject("Db2adminOrder").getString("desc"));
    System.out.println(
    "QTY is "+Row.getDataObject("Db2adminOrder").getInt("qty"));
    System.out.println(
    "======================================================");

  16. 创建一个名为 CheckForPremiumCustomer 的 Choice 组件。在 Case 组件中插入下面的 Java 代码:

    清单 13. CheckForPremiumCustomer Case 语句
    String premiumCode = "222";
    String orderId =
    Integer.toString(Row.getDataObject("Db2adminOrder").getInt("orderid"));
    if(3 > orderId.length()) return false;
    else return orderId.substring(0,3).equals(premiumCode);

  17. 在 Case 组件下面,使用下面的 Java 代码创建一个名为 SendFeedbackSurvey 的 Java Snippet:

    清单 14. SendFeedbackSurvey 代码片段
    System.out.println(
    "+++++ Premium customer order deleted. Feedback survey send. +++++");

  18. 与前面一样创建 Otherwise 和 no-op 组件。
  19. OrderDeleteProcess 执行相关检查,以确定 orderId 的前三个数字是否为“222”。如果是,则认为该订单与某个优惠客户相关联,并发送反馈调查。该流程看起来应该与图 20 完全相同。

    图 20. 订单删除业务流程

  20. 切换回组装关系图并创建一个选择器组件。将该选择器命名为 SelectBusinessProcess。
  21. 添加 JDBCInboundInterface 作为该选择器的界面。
  22. 右键单击 SelectBusinessProcess 并从下拉菜单中选择 Wire (Advanced)。选中所有业务流程界面:OrderCreate、OrderUpdate 和 OrderDelete。单击 OK。
  23. 双击 SelectBusinessProcess 以实现该组件,并对文件夹选择 com/ibm/selectors。
  24. 对于每个 JDBCInboundInterface 操作,将 Default Destination 设置为对应的 BusinessProcess。例如,选择 createDb2adminOrder,并对 Default Destination 选择 OrderCreateProcess,如图 21 所示。

    图 21. 业务流程选择器实现

该示例应用程序的开发到此就完成了!您的最终组装关系图看起来应该类似图 22。

 图 22. 最终组装关系图
重要:在继续之前,为确保您的工作区进行正确的构建,建议您执行下列步骤:
选择 Project => Clean => Clean All Projects。



 测试应用程序

本部分使用 Test Component Wizard 来测试该业务流程,并最终通过在 DB2 中填充 ORDER 表来测试整个应用程序。

  1. 在 Server 选项卡下启动 WebSphere Process Server。
  2. 右键单击 SelectBusinessProcess 并选择 Test Component,从而显示 Test Component Wizard。
  3. 缺省情况下,Test Component Wizard 模拟下游 SCA 组件,这不是我们需要的结果。为删除模拟器,请选择 Configuration 选项卡并选择删除所有三个模拟器,如图 23 所示。

    图 23. 从 Test Component 对话框删除模拟器

  4. 切换回 Events 选项卡。填充 createDb2adminOrder 操作,如图 24 所示。您应该获得对应的控制台输出。

    图 24. 针对 OrderCreateProcess 的 Test Component Wizard

  5. 确保还要测试 updateDb2adminOrder 和 deleteDb2adminOrder 操作。
  6. 若要使用实际的数据库驱动的事件来测试整个应用程序,请再次打开 DB2 命令中心。

    图 25. 打开 ORDER 表

    您应该看到类似于图 26 的对话框。
  7. 单击 Add Row 可以创建一个表行,单击 Delete Row 可删除一个行。若要更新某个行,只需编辑相应字段。
  8. 单击 Commit 以最终确定对 ORDER 的更改并触发入站适配器。

    图 26. 编辑 ORDER 表

结束语

本文介绍了使用 WebSphere 和 DB2 组合的数据库驱动的业务流程,但愿您会发现它是及时和有用的。我们介绍了数据库驱动的业务流程是什么、为什么以及何时应该使用它们,并提供了一个详细的逐步示例,展示如何使用 WebSphere Process Server 平台来实现此类业务流程。现在您已经完成了配置和开发该客户订单示例应用程序的步骤,您可以使用本文提供的信息,通过开发自己的数据库驱动的业务流程来最大化组织的效率。

 

组织简介 | 联系我们 |   Copyright 2002 ®  UML软件工程组织 京ICP备10020922号

京公海网安备110108001071号