实体数据任务

概览

实体数据任务(Entity Data Task) 或简称为 数据任务 是一种特殊的服务任务, 表示在流程中需要操作 Jmix 实体。 用实体数据服务操作数据相比常规服务任务更加方便。 可以从数据库加载实体、修改实体以及创建新实体。

准确地说,这里我们讨论的是 实体实例, 而不是 实体 本身。

图形表示法

实体数据任务在图中展示为圆角矩形,左上角有一个小的数据库图标。

data task

由于实体数据任务是 Jmix 扩展,第三方 BPMN 建模工具并不支持这种任务。如果需要与第三方建模工具交换 BPMN 模型,请注意兼容性。

例如,StormBPMN 不支持创建实体数据任务,因此需要使用服务任务代替,并且注释说明这是一个 实体数据任务。反之亦然,将 Jmix 的 BPMN 模型发布到 Storm 时,实体数据任务将在图中显示为常见的服务任务,但在 XML 中的属性配置仍然是安全的。

XML 表示

根据类型的不同,实体数据任务的 XML 表示形式会有所不同。请参阅相应任务类型介绍中的示例。

下面是一个新创建的实体数据任务,默认情况下,这是一个 加载实体 任务。

    <serviceTask id="entity-data-task" name="Entity Data Task"
        flowable:type="jmix-load-entities-jpql">
      <extensionElements />
    </serviceTask>

属性

实体数据任务有下列属性:

data task properties

配置数据任务时:

  • 首先,需要设置 通用任务属性

  • 然后,定义一个 任务类型 并根据所选的任务类型设置必要的参数。

  • 按需创建 执行监听器

  • 关于 异步(Async) 标记,详情参考 事务

实体数据任务没有可用的多实例属性。 但是可用在多实例的嵌入子流程中。 参阅 多实例

数据任务类型

数据任务的类型可以从下拉列表中选择:

data task types

类型包括:

删除实体时,请创建一个服务任务,然后通过 DataManager 进行删除。

加载实体

加载实体时,需要在属性面板中选择 Load Entities 任务类型。 然后定义 JPQL 查询语句 并按需添加 结果变量

JPQL 语句

点击如下图所示的编辑按钮可以创建一个 JPQL 查询语句:

load data task edit jpql

在打开的 JPQL 语句设计器 中,首先从下拉列表选择实体类,例如,smpl_Order。实体别名自动生成,可以后续修改。

jpql wizard

结果类型

然后,选择结果类型:

实体

查询语句返回实体列表。如果 Save result as 选择了 single element,则返回列表中的第一个元素,按默认排序或查询语句中设置的排序。

将生成如下 JPQL 语句:

select s from smpl_Order s
实体计数

查询语句返回一个 count 运算的整数值。

jpql count

将生成如下 JPQL 语句:

select COUNT(s) from smpl_Order s
元组

查询语句返回一组字段值,可以包含关联实体的字段。当选择 元组(Tuple) 时,会显示 Select 区域:

jpql tuple

必须选择一个属性以完成查询语句。例如,customer.name

attribute selection

将生成如下 JPQL 语句:

select s.customer.name from smpl_Order s

此外,还可以勾选 Distinct,得到唯一值。

jpql distinct

查询语句会被修改为:

select distinct s.customer.name from smpl_Order s
元组中只包含一个属性的值,如果选择了多个,其他属性将被忽略。

元组中也能使用 聚合(aggregation) 函数。

jpql tuple aggregation function

此时,查询语句返回单一数值。

jpql tuple aggregation

例如,这个查询语句计算所有订单的价格总和。

select SUM(s.amount) from smpl_Order s

过滤和排序

JPQL 中可以使用 WHEREORDER BY 子句:

jpql query conditions
WHERE 子句

JPQL 中的 WHERE 子句用于指定查询的过滤条件。点击 attribute icon 图标并选择一个实体属性,例如 amount

jpql where attribute

然后定义运算符:

jpql operations

JPQL 查询语句生成如下,返回金额大于参数 amount1 的订单列表:

select s from smpl_Order s where s.amount > :amount1

WHERE 子句中还可以使用 函数。点击 function icon 图标,选择一个函数并选择函数操作的属性:

jpql where function

查询必须返回金额大于参数值且在某个年份内(由另一个参数定义)的订单。

select s from smpl_Order s where s.amount > :amount1 and extract(year from s.approvalDate) = :year1

WHERE 子句中有多个条件时,可以选择条件之间的关系(and/or):

where and or
ORDER 子句

JPQL 中的 ORDER BY 子句用于对查询结果进行排序, 根据实体的一个或多个属性按升序或降序排列。 可以指定获取的记录的呈现顺序。

切换到 ORDER tab,然后选择要用于排序的属性。

jpql order

修改后的查询语句如下:

select s from smpl_Order s where s.amount > :amount1 and extract(year from s.approvalDate) = :year1 order by s.number asc

默认按升序排列,可以按下图所示调整排序:

order direction

点击 Copy 按钮可以将查询语句复制到剪贴板。

copy query button

查询语句参数

在 JPQL 语句中可以直接设置参数,例如:

select s from smpl_Order s where s.amount < 500

但是很多情况下,我们需要从外部传参,即在运行时传参。 因此,可以创建命名参数:

  • JPQL parameters — 这里可以定义参数:

create jpql parameter

定义的参数名必须与 JPQL 中的参数名相同。

参数值可以用以下两种方式传递:

  • 流程变量

  • 表达式

示例:

jpql parameters

使用结果

如需在流程中使用 JPQL 加载的结果,需要定义 结果变量(Result variable)。 可以选择已有的结果变量或通过输入新的变量名创建一个新的结果变量。

load task result variable

如果已有的结果变量类型与所需的类型不匹配,则会被覆盖。 结果变量的类型由查询语句的结果类型确定。

Save result as 中,还有两个选项,根据查询的结果可以选择 单一元素(Single element)集合(Collection)

load task save result
XML 表示

在 XML 中,加载实体数据任务是一个服务任务,但是使用自定义类型 flowable:type

<serviceTask id="load-orders-task" name="Load orders"
    flowable:type="jmix-load-entities-jpql"> (1)
  <extensionElements>
    <flowable:field name="jpql"> (2)
      <flowable:string>select s from smpl_Order s where s.amount &gt; :amount1</flowable:string>
    </flowable:field>
    <flowable:field name="resultVariable">
      <flowable:string>order</flowable:string> (3)
    </flowable:field>
    <flowable:field name="saveLoadResultAs">
      <flowable:string>collection</flowable:string> (4)
    </flowable:field>
    <flowable:field name="jpqlParameters"> (5)
      <flowable:string>[{"name":"amount1","valueType":"processVariable","value":"targetAmount"}]</flowable:string>
    </flowable:field>
  </extensionElements>
</serviceTask>
1  — 声明加载数据任务
2  — JPQL 查询语句
3  — 结果变量名
4  — 结果类型
5  — JSON 格式的查询参数

修改实体

可以修改存储在已有流程变量中的实体。实体类型将自动检测,支持修改所有非系统属性。

此外,还可以通过输入流程变量的名称来直接指定流程变量。 当变量未显示在列表中时,可以用这个方法。例如,变量是在服务任务中以编程方式创建的,或者是另一个数据任务加载实体的结果。 之后,需要显式定义实体类型并指定实体属性。

modify data task properties

指定属性

点击 Create 链接按钮创建需要修改的实体属性。

属性值可以通过下列方法之一设置:

  • 直接在字段内输入值:

    data task attribute direct

    枚举 中选择:

    data task attribute enum
  • 表达式:

    data task attribute expression

    名为 today 的流程变量必须在数据任务执行前定义。

  • 使用 Spring bean。

    默认情况下禁用该选项。 如需使用,需要设置应用程序属性:

    jmix.bpm.data-task-spring-bean-entity-attribute-enabled=true

    之后,在 Value type 字段可以选择 Spring bean

    spring bean option

    可以指定一个 Spring bean 及其方法为实体属性传值:

    spring bean value
XML 表示

在 XML 中,修改实体数据任务是一个服务任务,但是使用自定义类型 flowable:type。 修改实体的属性值通过 JSON 传入。

<serviceTask id="modify-order-task" name="Modify order"
    flowable:type="jmix-modify-entity"> (1)
  <extensionElements>
    <flowable:field name="entityName">
      <flowable:string>smpl_Order</flowable:string> (2)
    </flowable:field>
    <flowable:field name="processVariable">
      <flowable:string>order</flowable:string> (3)
    </flowable:field>
    <flowable:field name="entityAttributes">
      <flowable:string>[{"name":"approvalDate","valueType":"directValue"}]</flowable:string> (4)
    </flowable:field>
  </extensionElements>
</serviceTask>
1  — 声明任务类型
2  — 定义实体类
3  — 定义结果变量
4  — JSON 格式的实体属性

创建实体

创建实体时,从列表中选择实体名称。BPMN Inspector 中可以指定所有的非系统属性。

create data task properties

如果需要在后续流程中使用该实体,可以设置一个 Result variable 参数。

设置所有必须属性以及其他属性。

XML 表示

在 XML 中,创建实体数据任务是一个服务任务,但是使用自定义类型 flowable:type。 创建实体的属性值通过 JSON 传入。

<serviceTask id="create-order-task" name="Create order"
    flowable:type="jmix-create-entity"> (1)
  <extensionElements>
    <flowable:field name="entityName">
      <flowable:string>smpl_Order</flowable:string> (2)
    </flowable:field>
    <flowable:field name="resultVariable">
      <flowable:string>order</flowable:string> (3)
    </flowable:field>
    <flowable:field name="entityAttributes">
      <flowable:string>[{"name":"status","valueType":"directValue","value":"New"},{"name":"customer","valueType":"expression","value":"${customer}"}]</flowable:string> (4)
    </flowable:field>
  </extensionElements>
</serviceTask>
1  — 声明任务类型
2  — 定义实体类
3  — 定义结果变量
4  — JSON 格式的实体属性