列表（list）页面中，如何配置关联Domain（含hasMany）的属性作为查询条件呢?
李小翔
2013-11-04 16:26

内容列表

比如某个仓库软件中，入库单关联仓库，并且包含多条入库明细（物品），在入库单的列表中，需要如何配置，才可以根据仓库名称、入库明细的物品名称来查询呢？
领域类定义如下：
/** 仓库 */
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>