模块中的历史记录查询问题:
- 先是查询条件问题:查询条件分别有:简记码,货物名称,和仓库。需求中在页面上要显示的字段。简记码,名称,操作时间,类型(入库还是出库),单位,数量,库存余量,仓库名称,操作员。
- 显示的字段还好搞定。主要是前面三个字段,这个三个中,前两个还行,就是第三比较难搞。主要是这三个字段所属表和库存历史表的关系。goods(货物)表和history(库存历史表)是一对多,而store(仓库)和goods(货物表)是一对多。而store和history是没有关系的。
- 主要这里是多条件组合查询,就必须使用离线查询方法了。查询的条件的拼接和在Action中的到请求的条件这里都是不小的问题,属前者较难。这是持久层使用的是hibernate3。所以要使用离线查询,而且这里是or查询。
- 先是在页面中通过struts2标签将请求参数取到,还望说了这里的仓库是通过Ajax请求过来的,具体如下:
<s:textfield cssClass="tx" name="goods.innerNum"></s:textfield> <s:textfield cssClass="tx" name="goods.gname"></s:textfield> <select name="goods.store.sid" id="selectStores" class="tx" style="width: 120px;">
- 然后是查询条件的拼接:在这里要看一下history表的结构
- 要查历史记录的话,肯定是查货物的,所以只要将前面三个条件对应的所有goodsId找出来就行,这是or所以可以使用in。所以说前面两个还比较好弄,主要是第三个是对应多个goodsId,并且可能没有goodsId。前面两个当然也可能没有。这是后话。
- 既然可以这样,那就是开始实现了。前两个都没任何问题,就是直接查询的到就行。到第三个条件的时候,我在想要不要通过store表来查询呢,可能受原来项目的影响。涉及到很多字段的时候,就想用到有字段的表。但是后来一想,完全没必要只使用history和store这两张表就行,页面上传来的就是storeId。通过goods表查询条件就是g.storeId=?。返回的是一个List集合。取出goodsId就行。到这里所有满足三个条件的goodsId都取到。下面就是拼接了。
- 这里使用DetachedCriteria detachedCriteria = DetachedCriteria.forClass(History.class);这个类进行拼接。具体实现如下:
public List<History> findHistory(History history) { DetachedCriteria detachedCriteria = DetachedCriteria.forClass(History.class); List<String> goodsIds = new ArrayList<String>(); if(history.getGoods().getInnerNum()!=null&&history.getGoods().getInnerNum().trim().length()>0){ List<Object> listObject = goodsDao.findByinnerNum(history.getGoods().getInnerNum()); goodsIds.add((String)listObject.get(0)); } if(history.getGoods().getGname()!=null&&history.getGoods().getGname().trim().length()>0){ List<Object> listObject = goodsDao.findByGname(history.getGoods().getGname()); goodsIds.add((String)listObject.get(0)); } if(history.getGoods().getStore().getSid()!=null&&history.getGoods().getStore().getSid().trim().length()>0){ List<Object> listObject = goodsDao.findByGid(history.getGoods().getStore().getSid()); if(listObject.size()>0){ for(Object object:listObject){ goodsIds.add((String)object); } }else{ goodsIds.add("数据库中没有货物"); } } if(goodsIds.size()>0){ detachedCriteria.add(Restrictions.in("goods.gid", goodsIds)); } List<History> hs = historyDao.findHistory(detachedCriteria); System.out.println(hs); return hs; }
- 可能还有些要优化的地方,并且有些地方根本写的不符合规范。因为着急,就先这样记下来。这里其实有很多问题,如果用户只输入一个条件,恰好这个条件没有历史记录,如果不进行过滤的话就会出现数组越界问题。就是你过滤了,还有一个问题,就是当离线查询里面没有条件添加时,如果你就直接传过去,那就是一条错误的SQL语句。这时候要过滤条件,有条件的时候才添加。但是这里还有问题,当输入条件不存在记录时,你过滤不添加条件,到最后就会查询全部,所以要在输入条件不存在记录时,给它添加一个不存在的条件。让它查询不出结果。否则就会查询出全部。