比如某个仓库软件中,入库单关联仓库,并且包含多条入库明细(物品),在入库单的列表中,需要如何配置,才可以根据仓库名称、入库明细的物品名称来查询呢?
领域类定义如下:
/** 仓库 */
class Warehouse {
    /** 仓库名称 */
    String name
    
    static hasMany = [goodsIns: GoodsIn]
}
/** 入库单 */
class GoodsIn {
    /** 入库单号 */
    String number
    /** 仓库 */
    static belongsTo = [warehouse: Warehouse]
    
    /** 入库物品明细 */
    static hasMany = [items: GoodsInItems]
}
/** 入库物品 */
class GoodsInItem {
    /** 物品名称 */
    String name
    
    /** 入库单 */
    static belongsTo = [goodsIn: GoodsIn]
}
入库单的列表视图(list.gsp)中,配置查询条件:
- 入库单号:属于入库单的属性,因此直接配置为 number
- 仓库名称:属于入库单关联的仓库的属性,因此配置为“仓库属性名.仓库名称属性名”,即 warehouse.name
- 物品名称:属于入库单关联的,并且是hasMany一方的入库物品的属性,必须使用子查询,因此在 s:textField 中配置一个 onsearch 的事件,调用一个自定义方法(事件中的this、hql参数名固定),转换成一个子查询的HQL
配置完成后,使用 BroFramework 的控制器脚手架模板生成的list操作就可以自动解析、并返回正确的查询结果了。
示例代码如下:
<s:form action="${actionName}"><s:setup/><div class="body">
    
    ......
    
    <s:filter>
        <div class="right">
            入库单号:<s:textField name="number" />
            仓库名称: <s:textField name="warehouse.name" />
            物品名称: <s:textField name="it.name" onsearch="searchItems(this, hql)" />
            <script>
            function searchItems(el, hql) {
                if ( hql ) {
                    return "(id in (select gi.id from GoodsIn gi left join gi.items it where " + hql + "))"
                }
            }
            </script>
            <s:submitButton/>
        </div>
    </s:filter>
    ....
</div></s:form>