3.6.2.2.2. 查询参数

数据源中的 JPQL 查询语句可能包含几种不同类型的参数。参数类型是通过参数名称的前缀决定的,参数名称中 $ 符号之前的部分就是名称前缀,下面针对不同的前缀分别介绍一下 $ 符号之后部分的理解。

  • ds 前缀

    这个参数的值是在同一个 DsContext 注册的其它数据源的数据。示例:

    <collectionDatasource id="customersDs" class="com.sample.sales.entity.Customer" view="_local">
        <query>
             <![CDATA[select c from sales$Customer c]]>
        </query>
    </collectionDatasource>
    
    <collectionDatasource id="ordersDs" class="com.sample.sales.entity.Order" view="_local">
        <query>
             <![CDATA[select o from sales$Order o where o.customer.id = :ds$customersDs]]>
        </query>
    </collectionDatasource>

    上面这个例子中,ordersDs 数据源的查询参数是 customersDs 数据源当前加载的实体实例。

    如果使用了 ds 开头的参数,会自动创建数据源之间的依赖关系。因此能在参数变化了的情况下数据源自动更新。比如在上面的例子中,如果选择的 Customer 改变了,Order 的列表会自动更新。

    需要注意的是,在上面这个带参数的查询中,等号左边的部分是 o.customer.id 标识符的值,右边部分则是 customersDs 数据源中的 Customer 实例。这个等式能成立是因为在 Middleware 运行这个查询的时候,Query 接口的实现类会在给查询参数赋值的时候自动将实体的实例替换成实体的 ID。

    也可以在 $ 符号后面的数据源中使用实体关系图(entity graph)中的路径来指定一个深层的属性(直接用这个属性的值),示例:

    <query>
        <![CDATA[select o from sales$Order o where o.customer.id = :ds$customersDs.id]]>
    </query>

    或者

    <query>
        <![CDATA[select o from sales$Order o where o.tagName = :ds$customersDs.group.tagName]]>
    </query>
  • custom 前缀

    参数值会从传给数据源 refresh() 方法的 Map<String, Object> 对象中获取。示例:

    <collectionDatasource id="ordersDs" class="com.sample.sales.entity.Order" view="_local">
        <query>
            <![CDATA[select o from sales$Order o where o.number = :custom$number]]>
        </query>
    </collectionDatasource>
    ordersDs.refresh(ParamsMap.of("number", "1"));

    如果需要的话,这里也会将实体实例转成标识符,这个机制跟 ds 前缀里面描述的类似。但是这里不支持实体关系图路径。

  • param 前缀

    参数值从传递给界面控制器 init() 方法的 Map<String, Object> 对象中获取。示例:

    <query>
        <![CDATA[select e from sales$Order e where e.customer = :param$customer]]>
    </query>
    openWindow("sales$Order.lookup", WindowManager.OpenType.DIALOG, ParamsMap.of("customer", customersTable.getSingleSelected()));

    如果需要的话,这里也会将实体实例转成标识符,这个机制跟 ds 前缀里面描述的类似。这里也支持使用实体关系图路径的参数名称。

  • component 前缀

    使用一个可视化组件当前的值作为参数值,通过参数名称来定义组件路径。示例:

    <query>
        <![CDATA[select o from sales$Order o where o.number = :component$filter.orderNumberField]]>
    </query>

    组件的路径需要包含所有嵌套的界面子框架

    如果需要的话,这里也会将实体实例转成标识符,这个机制跟 ds 前缀里面描述的类似。这里也支持使用实体关系图路径的参数名称,但是实体属性的路径要继续添加在组件路径之后。

    数据源不会因为组件的值改变而自动刷新。

  • session 前缀

    用户会话的属性中获取跟参数名称相同的属性值作为参数值。

    通过 UserSession.getAttribute() 方法获取这个值,所以会话中预定义的名称都支持。

    • userId – 当前注册用户或者被替代用户的 ID;

    • userLogin – 当前注册用户或者被替代用户的用户名(英文小写)。

    示例:

    <query>
        <![CDATA[select o from sales$Order o where o.createdBy = :session$userLogin]]>
    </query>

    如果需要的话,这里也会将实体实例转成标识符,这个机制跟 ds 前缀里面描述的类似。但是这里不支持实体关系图路径。