ext+java综合查询解决方案

软件开发完成,客户突然要求可以实现按照所有字段进行查询,由于项目工程比较大,每个页面需要添加一个查询窗口,后台需要依据传入参数进行改写hql或者sql语句,这样工作量很大,于是有了以下解决方案:

  (1)每个查询为了美观,可以再ext基础上弹出一个查询界面。由于添加窗口是好的,可以基于添加窗口,界面不做任何调整,窗口里面的处理方法写为通用的,这样减少了页面维护工作。

  (2)基于查询需要支持> ,< =,包含等比较,再输入框中输入>,<,=默认为包含,然后让输入值,比如要查询价格大于0.8的,在文本框中输入>0.8

  (3)本软件使用ext3.0 struts 2.1 herbernate3版本,struts接受参数,会自动设置参数,并封装如对象,可以做一个方法传入一个对象依据这个对象进行中和查询,由于客户端传入的参数为>0.8无法转化为需要的float类型,在这里配置过滤器,将>过滤,然后把传入的name(key)与value(value)放入session

  (4)创建查询分析器 遍历session中所有的值,并用正则表达式过滤掉所有的其他非必要信息。然后依据java反射动态调用方法。但由于某些查询设计到外键,也就是herbernate中的子对象,一级一级调用get方法最后依据AbstractEntityPersister获取最后一个对象的主键字段名称,进行hql语句拼写,然后设置参数,并查询,由于接口需要通用性强,返回一个泛型,增强了程序的通用性。

以下为关键部分代码加说明:

  (1)页面ext查询界面实现

  //创建查询
                var createselectWindow = function(){
                    var postForm = new Ext.form.FormPanel({
                        rederTo:'createWin',
                        width:350,height:450,frame:true,
                        layout:'form',labelWidth:60,labelAlign:'right',
                        items:[client_clientname,client_clientpersonname,client_clientpersontel,client_clienttype],
                        buttonAlign:'center',
                        buttons:[{xtype:'button',text:'查询',
                            handler:function(){   

            //详细下面有改方法
                                var param = getFormJson(postForm);

            //将json转换为对象
                                var Object=Ext.decode(param);

           //防止分页,刷新丢失查询条件
                                store.on("beforeload", function(){Ext.apply(this.baseParams,Object);});
                                //重现加载store
                                store.load({params:Object});
                            }
                        },{
                            text:'取消',
                            handler:function(){
                                postWindow.destroy();
                            }
                        }]
                    });
                    var postWindow = new Ext.Window({
                        title:'客户信息查询',width:300,height:190,
                        collapsible:true,maximizable:true,
                        layout:'fit',plain:true,modal:'true',items:postForm
                    });
                    postWindow.show();
                    return postForm;
                };

//中间设计到的其他关键代码

      //将form表单中的所有提交内容准换为json格式

      function getFormJson(postForm){
          var param = '{';  
          postForm.getForm().items.each(function(f,index,length){  
            var tmp = '"' + f.getName() + '":"' + f.getValue() + '",';  
            param +=  tmp;  
            });  
          param = param.substr(0,param.length - 1)         
          param+="}";
        return param;
      }
    function select(postForm,store){
        //将form中的参数转化为json
        var param = getFormJson(postForm);
        //将json转化为对象
        var Object=Ext.decode(param);
        //防止分页丢失数据 刷新丢失数据
        store.on("beforeload", function(){Ext.apply(this.baseParams,Object);});
        //一句查询参数重新加载数据
        store.load({params:Object});
    }

  这样提交请求就没有什么问题了,以后为后台主要代码:

    

   public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
    
        // TODO Auto-generated method stub
        UserIncep ui = new UserIncep();
        HttpServletRequest request1 = (HttpServletRequest) request;
        String action = request1.getServletPath();

    //过滤掉< > =生成新的request对象,防止>0.1被当成字符串处理,这个方法下面有解释
        ParameterRequestWrapper ppw=JsonUtil.getRequestParams((HttpServletRequest) request);
        String params = ppw.getParamsjson();
        String uri = request1.getRequestURI();// 返回请求行中的资源名称
        String url = request1.getRequestURL().toString();// 获得客户端发送请求的完整url
        String ip = request1.getRemoteAddr();// 返回发出请求的IP地址
        String host = request1.getRemoteHost();// 返回发出请求的客户机的主机名
        int port = request1.getRemotePort();// 返回发出请求的客户机的端口号。

  //继续调用,这里用ppw,不用原来的request
        chain.doFilter(ppw, response);
        return ;
    }

 

转化请求参数处理方法 

    //通过获取request里面的所有参数,去掉< > =生成新的request,保留原来request中的数据

    public static ParameterRequestWrapper getRequestParams(HttpServletRequest request) {
        Enumeration enu = request.getParameterNames();
        StringBuffer sb=new StringBuffer();
        HashMap m=new HashMap(request.getParameterMap());  
        HttpSession  session=request.getSession();
        int count=0;
        String setstr=null;
        while (enu.hasMoreElements()) {
            String paraName = (String) enu.nextElement();
            String requeststr = request.getParameter(paraName);
            //System.out.println(paraName.substring(paraName.lastIndexOf(".")+1, paraName.length()));
            count=FormatUtil.getCount(paraName, "\\.");
             setstr=paraName.substring(paraName.lastIndexOf(".")+1, paraName.length());
            //count==1?requeststr.substring(1, requeststr.length()):requeststr
            if(requeststr.startsWith(">")){
                m.put(paraName, requeststr.substring(1, requeststr.length()));
                session.setAttribute(count==1?setstr:requeststr, HqlEnum.MORE);
                }
            else if(requeststr.startsWith("<")){
                m.put(paraName, requeststr.substring(1, requeststr.length()));
                session.setAttribute(count==1?setstr:requeststr, HqlEnum.LESS);
                }
            else if(requeststr.startsWith("=")){
                m.put(paraName, requeststr.substring(1, requeststr.length()));
                session.setAttribute(count==1?setstr:requeststr, HqlEnum.EQ);
                }
            else {
                m.put(paraName, requeststr);
                session.setAttribute(count==1?setstr:requeststr, HqlEnum.Like);
                }
                //name.age.page
        sb.append(paraName).append("=").append((requeststr)).append("&");
        }
    
         ParameterRequestWrapper wrapRequest=new ParameterRequestWrapper(request,m);
         wrapRequest.setParamsjson(sb.toString());
        return wrapRequest;
    }

依据对象查找数据库方法 

//依据obj查找合适的对象

 public  Query getHql(Object obj,SessionFactory sf){
    if(obj==null){
        return null;
    }
    List<Object>object=new ArrayList<Object>();
    Class oclass=obj.getClass();
    String classname=oclass.getSimpleName();
    Field fields[]=oclass.getDeclaredFields();
    Object returnvalue=null;

  //查询所有数据的hql语句
    StringBuffer sqlsb=new StringBuffer("from "+classname+" abstfind ");

  //查询总数量的hql语句
    StringBuffer sizebuff=new StringBuffer("select count(*) from "+classname+" abstfind ");
    boolean b=true;
    HttpServletRequest request=ServletActionContext.getRequest();

//获取session中所有的名称
    Enumeration<String> s=request.getSession().getAttributeNames();
    String sessionname=null;
    Object sessionvalue=null;

  String selname="";

//遍历session中的值
    while(s.hasMoreElements()){
        sessionname=s.nextElement();
        sessionvalue=(String) request.getSession().getAttribute(sessionname);

    //过滤其他session数据
        if(sessionname.contains(".")){
        try {
            //动态方法调用 client.product.name 会调用client对象的getProduct()方法,并用返回值调用getName()方法,最后返回getName()的返回值
            returnvalue = geterMethodInvoke(sessionname, obj);
            if(null!=returnvalue){
                //如果是hibernate对象,则按照子对象主键查询=
 
        
                //如果是基本了类型或者String 从session里面对于的比较关系,然后按照关系进行比较查询
                Object sobj=ServletActionContext.getRequest().getSession().getAttribute(sessionname);

      //初始化基本查询selname给对象起别名
                                      if(b){selname=sessionname.substring(0,sessionname.indexOf("."));sqlsb.append(selname).append(" where ");b=false;}
                    if(sobj!=null){
                     if(sobj==HqlEnum.MORE){

        //将需要传递的参数放到集合中方便设值
                        object.add(returnvalue);

        //组合查询语句
                        sqlsb.append(selname).append(sessionname).append(">?");sqlsb.append(" and ");
                        sizebuff.append(selname).append(sessionname).append(">?");sqlsb.append(" and ");
                    }else if(sobj==HqlEnum.LESS){
                        object.add(returnvalue);
                        sqlsb.append(selname).append(sessionname).append("<?");sqlsb.append(" and ");
                        sizebuff.append(selname).append(sessionname).append(">?");sqlsb.append(" and ");
                    }else if(sobj==HqlEnum.EQ){
                        object.add(returnvalue);
                        sqlsb.append(selname).append(sessionname).append("=?");sqlsb.append(" and ");
                        sizebuff.append(selname).append(sessionname).append("=?");sqlsb.append(" and ");
                    }else if(sobj==HqlEnum.Like){
                    object.add("%"+returnvalue+"%");
                        sqlsb.append(selname).append(sessionname).append(" like ?");sqlsb.append(" and ");
                        sizebuff.append(selname).append(sessionname).append(" like ?");sqlsb.append(" and ");
                }
            }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        }
    }

//去掉最后一个and语句
    String hql=sqlsb.substring(0, sqlsb.length()-4);
    String hqlbuff=sizebuff.substring(0, sqlsb.length()-4);
    Query query=sf.getCurrentSession().createQuery(hql);
    Query querybuff=sf.getCurrentSession().createQuery(hql);
    //将值设值到查询中
    int i=0;
    for(Object o:object){
        try {

    //依据对象类型,动态调用query的方法
            query.getClass().getMethod("set"+o.getClass().getSimpleName(),new Class[]{int.class, o.getClass()}).invoke(query, new Object[] {i,o});
            i++;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

  //保存数据总数
    maxsize=Integer.parseInt(querybuff.uniqueResult().toString());
    return query;
}

 

以下为动态方法调用接口

public Object geterMethodInvoke(String str,Object obj){
    String fieldstrs[]=str.split("//.");
    boolean b=true;
    Object returnvalue=null;
    try {
    for(String s:fieldstrs){
        if(b)
            b=false;
        else if(returnvalue==null)
        returnvalue=obj.getClass().getMethod("get" + FormatUtil.toUpperCaseFirstOne(s), new Class[] {})
                .invoke(obj, new Object[] {});
        else{
            returnvalue=obj.getClass().getMethod("get" + FormatUtil.toUpperCaseFirstOne(s), new Class[] {})
            .invoke(returnvalue, new Object[] {});
        }
    }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return returnvalue;
}

posted @ 2014-02-14 10:30  流氓剑客  阅读(369)  评论(0)    收藏  举报