动态sql之我见(字段名动态生成)

http://blog.sina.com.cn/s/blog_4c925dca0100ehr0.html

态sql这个话题,应该说不是什么新鲜事情了!但是,在一些特殊场合,我们就会要用到动态sql,如果是第一次去用动态sql的话,估计不会那轻松。这里阿堂把自己在项目中用动态sql的过程,和朋友们分享一下!
 

    我这里所说的动态sql,是指的select语句中后面跟的字段是不确定的,是要根据实际业务来拼成的select语句。并不是简单指select后面的where条件是动态变化的
    我的实际业务情况如下
     运输公司在web页面,根据相应条件查询后,得到的select语句后字段都不确定,如,有时候,可能是select a,b,c,有时候可能又会是selecte,f,g,h,i,j等,然后,还要将这些查询得到的记录下载到excel文件中,也就是说每次查询后,得到的记录列字段都有可能不一样,生成的excel文件中的字段也是不一样的(除了行数,不确定外,列名也是不确定的),所以程序中就不能写死了,就得要去判断了,阿堂这里用到ResultSetMetaData类,实际上ResultSetMetaData应该是用到了反射技术的。。也就是我们只要得到一个ResultSet对象如rs,我们就可以得到
ResultSetMetaData类的对象了,进而,可以得到记录的总行数,记录的总列数,记录的列名,列字段的字段类型等,这时候,我们就可以将每一行记录封装到一个List对象中,然后,将每一个List对象,再封装到一个总的List对象中,最后利用jxl包中的一些方法,写入到excel文件中就可以了,当然,其中还会涉及到很多的细节性方面的东西,这不是我这里需要讨论的细节了,所以,我就不对此展开了,如有疑问,可以给阿堂单独留言咨询讨论!

(这是一个原来的项目,就是用的jdbc来操作的。。如果是这种动态的sql,用hibernate,ibatis这些框架处理起来就绝非易事了)

 

处理记录ResultSet集的类

public class MyTableModel extends AbstractTableModel {
 
 
 private static final long serialVersionUID =-5361448825948488492L;
 
    ResultSetrs;       
   ResultSetMetaData rsmd; 
 
   //以一个ResultSet结果集构造TableModel构造函数
    publicMyTableModel(ResultSet rs)
         
           this.rs=rs;
           try{               
                   rsmd=rs.getMetaData();
           }
           catch(Exception e)
           {
                   e.printStackTrace();
           }
    }
 

   
   //重写getColumnCount方法,用于设置该TableModel的列数
    public intgetColumnCount()
    {
           try {
                   return rsmd.getColumnCount();
           }
           catch (SQLException e)
           {
                   
                   e.printStackTrace();
                   return 0;
           }
    }

   //重写getRowCount方法,用于设置该TableModel的行数
    public intgetRowCount() {
           try{
                   rs.last();
                   return rs.getRow();
           }
           catch(Exception e)
           {
                   e.printStackTrace();
                   return 0;
           }
                   
    }
   
   //重写getValueAt方法,用于设置该TableModel指定单元格的值
    publicObject getValueAt(int row, int column) {
           
           try{
                   rs.absolute(row+1);               //定位到column列
                   returnrs.getObject(column+1);               
           }
           catch(SQLException e)
           {
                   e.printStackTrace();
                   return null;
           }
    }
   
   //重写getColumnName方法,用于为该TableModel设置列名
    publicString getColumnName(int c){
           try{
                   return rsmd.getColumnName(c+1);
           }
           catch(SQLException e)
           {

                   e.printStackTrace();
                   return null;
           }
       
}

 

业务类中的一个处理方法

 public ResultSet SelectBill3(Date sdate,Dateedate,String content,String username,String type) throwsSQLException
 {
  Date ed1=edate;
  ed1.setDate(ed1.getDate()+1);  
  //如下这个要拼成动态sql语句a
  StringBuffer str=newStringBuffer("");  
  StringBuffer sb=newStringBuffer("");
  Stringstr1="";  
  String str11="";
  if(type.equals("billdate"))
  {
   str11="selectdistinct fylx from BillOrderCheck bo,o_fy ofy wherebo.BillDate>=? andbo.BillDate<?  andbo.UserName=?  and bo.billno=ofy.zdbh";
   str1="selectbo.BillNo as 帐单号,bo.BillDate as 帐单日期,bo.AllocateNo as派车单号,bo.OrderNo as 订单号,bo.TransDate as 运输日期,bo.VehicleNo as车牌,bo.CaseNo as 车型柜号,bo.Route as 行车路线,"
    +"sum(o_fy.ysfje)as合计费用";   
  }
  //运输日期 add by heyitang200903041335
  if(type.equals("allocatenodate"))
  
   str11="selectdistinct fylx from BillOrderCheck bo,o_fy ofy wherebo.TransDate>=? andbo.TransDate<?  andbo.UserName=?  and bo.billno=ofy.zdbh";
   str1="selectbo.BillNo as 帐单号,bo.BillDate as 帐单日期,bo.AllocateNo as派车单号,bo.OrderNo as 订单号,bo.TransDate as 运输日期,bo.VehicleNo as车牌,bo.CaseNo as 车型柜号,bo.Route as 行车路线,"
    +"sum(o_fy.ysfje)as合计费用";     
  }
  //运输日期和派车单的组合条件 add by heyitang200903041335
  if(type.equals("transAndDate"))
  {
   str11="selectdistinct fylx from BillOrderCheck bo,o_fy ofy wherebo.TransDate>=? and bo.TransDate<?and bo.AllocateNo=?  and bo.UserName=? andbo.billno=ofy.zdbh";   
   str1="selectbo.BillNo as 帐单号,bo.BillDate as 帐单日期,bo.AllocateNo as派车单号,bo.OrderNo as 订单号,bo.TransDate as 运输日期,bo.VehicleNo as车牌,bo.CaseNo as 车型柜号,bo.Route as 行车路线,"
    +"sum(o_fy.ysfje)as合计费用";    
  }
  
  //帐单日期和派车单的组合条件
  if(type.equals("allocatenoAndDate"))
  {
   str11="selectdistinct fylx from BillOrderCheck bo,o_fy ofy wherebo.BillDate>=? and bo.BillDate<? andbo.AllocateNo=?  and bo.UserName=? andbo.billno=ofy.zdbh";    
   str1="selectbo.BillNo as 帐单号,bo.BillDate as 帐单日期,bo.AllocateNo as派车单号,bo.OrderNo as 订单号,bo.TransDate as 运输日期,bo.VehicleNo as车牌,bo.CaseNo as 车型柜号,bo.Route as 行车路线,"
    +"sum(o_fy.ysfje)as合计费用";   
  }
  Connection conn=null;
  GetConnection gc=newGetConnection();
  conn=gc.getConnection();
  PreparedStatementpst=null;
  ResultSet rs=null;
  ResultSet rs1=null;
  try
  {
   //拼接sql语句
   pst=conn.prepareStatement(str11);
   if(type.equals("billdate")|| type.equals("allocatenodate"))
      
    pst.setDate(1,(java.sql.Date)sdate);       
    pst.setDate(2,(java.sql.Date) ed1); 
    pst.setString(3,username); 
   }
   
   if(type.equals("allocatenoAndDate")|| type.equals("transAndDate"))
   {
    pst.setDate(1,(java.sql.Date)sdate);        
    pst.setDate(2,(java.sql.Date) ed1);
    pst.setString(3,content.trim()); 
    pst.setString(4,username); 
   }
   rs1=pst.executeQuery();  
   intcount=0;  
   
   //获得并集最多的费用类型
   while(rs1.next())
   {
    if(count>=1)str.append(";");    
    str.append(rs1.getString("fylx"));
    //stradd.append(cs.converString(rs1.getString("fyzwmc")));
    str.append("-");
    str.append(getFyzwmc(rs1.getString("fylx")).replace("/",""));
    count++;
   }
   rs1.close();
   
   String[]strarr=str.toString().split(";");   
   sb.append(str1);
   intlength=strarr.length;
   Strings="",s1="",s3="",fylx1="",fyzwmc1="";
   //下面循环得到拼接的动态sql语句
   for(inti=0;i<length;i++)
   {
    
    sb.append(",");
    //得到类似'YF' 
    s=strarr[i];
    //System.out.println("strarr[i]"+strarr[i]);
    fylx1=s.substring(0,s.indexOf("-"));
    fyzwmc1=s.substring(s.indexOf("-")+1);
    //得到类似ofy.YF
    s1="o_fy.fylx";      
    s3="sum(case"+s1;
    s3=s3+"when '"+fylx1+"' then ";
    s3=s3+"o_fy.ysfje";
    s3=s3+"else";
    s3=s3+"0";
    s3=s3+"end) as "+fyzwmc1;
    sb.append(s3);
   }
   sb.append("from BillOrderCheck bo,allocate_m am,o_fy wherebo.allocateno=am.allocate_no and o_fy.zdbh=bo.billno");
   
   //动态拼sql语句
   if(type.equals("billdate"))
   {
    sb.append("and  bo.BillDate>=? andbo.BillDate<? and bo.UserName=? ");
   }
   if(type.equals("allocatenodate"))
   {
    sb.append("and  bo.TransDate>=? andbo.TransDate<? and bo.UserName=? ");
   }
   if(type.equals("allocatenoAndDate"))
   {
    sb.append("and bo.BillDate>=? and bo.BillDate<?and bo.AllocateNo=? and bo.UserName=? ");
   }
   if(type.equals("transAndDate"))
   {
    sb.append("and  bo.TransDate>=? andbo.TransDate<? and bo.AllocateNo=? and bo.UserName=?");
   }
   
   sb.append("group byBillNo,BillDate,AllocateNo,OrderNo,TransDate,VehicleNo,CaseNo,bo.Route");

   pst=conn.prepareStatement(sb.toString(),ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);  
   if(type.equals("billdate")|| type.equals("allocatenodate"))
   {
    pst.setDate(1,(java.sql.Date)sdate);       
    pst.setDate(2,(java.sql.Date) ed1); 
    pst.setString(3,username);     
   }
   
   if(type.equals("allocatenoAndDate")|| type.equals("transAndDate"))
   {
    pst.setDate(1,(java.sql.Date)sdate);        
    pst.setDate(2,(java.sql.Date) ed1);
    pst.setString(3,content.trim());  
    pst.setString(4,username);    
   }

   rs=pst.executeQuery();  
   booleanflag=false;
   if(rs.next())
   {
    flag=true;
   }
   if(flag)
   returnrs;
   else
    returnnull;
  }
  catch(SQLException e)
  {
   e.printStackTrace();
   returnnull;
   
 


 public List<Object>getList(MyTableModel model)
 {
  List<Object> list=newArrayList<Object>();
        int a1=model.getColumnCount();
        int a2=model.getRowCount();
        List<Object> list1=newArrayList<Object>();        
        
        for(int j=0;j<a1;j++)
       
     list1.add(model.getColumnName(j));     
              
        list.add(list1);
       
        for(int i=0;i<a2;i++)
        {
          List<Object>list2=new ArrayList<Object>();
          for(int j=0;j<a1;j++)
                      
          list2.add(model.getValueAt(i,j));
          }
         list.add(list2);         
              
   return list;
 }

 

动态sql之我见(字段名动态生成)

 

动态sql之我见(字段名动态生成)

 

动态sql之我见(字段名动态生成)


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值