赛迪网 > IT技术 Java > 技术动态
  IT资讯搜索
 
IT产品搜索
[程序开发][网管世界][网络安全][数据库技术]
[操作系统][嘉宾聊天·在线访谈][活动集锦]
[精彩专题][Symantec专区][订阅IT技术周刊]
[开发论坛][网管论坛][安全论坛][数据库论坛]
[操作系统论坛][Sybase专区][IBM dW技术专区]
[病毒求助][病毒与漏洞播报][文档·源码下载]

超级简单的 sqlmap 工具(ajf sql map)

发布时间:2007.12.29 04:58     来源:赛迪网    作者:giscat

超级简单的sqlmap工具

以前也写过一个,
这一把加入了动态sql,全部重写了

与ibatis类似
#param_name#  使用参数 ?(暂时不支持)
$param_name$  直接替换 

本工具特点:

提供了对ibatis常见功能的支持
核心类只有一个SqlMap.java 
本工具适用与综合查询 (insert与update不推荐使用)
动态sql语句只支持  条件 (这个最常用了)


    //根据 content
 动态生成 sql
    //参数xxx不为空时,才输出 content,实现动态sql
    //目前只支持常见的notempty判断
    //可使用模板来动态生成sql语句,这样将非常强大,常见的模板工具有 freemark,velocity等
    //只是一个简单的查询工具,就不使用第三方的模板工具了
    //{xxx}  xxx 参数名

配置文件使用纯文本格式,而非xml格式(有些特殊字符XML里搞来搞去很无趣)
配置文件格式 ajf_sql_map(xxx)=select * from x   ,xxx表示sql name
传入参数直接替换,参数封装在map中
查询返回结果,记录行映射为map,key值从resultset的元数据中获取,且全部为小写,可参考作后的 rs2list部分代码
其他代码不一一给出,稍微搞一下即能整出来
sql-map配置文件只提供一个(统一配置管理,分散配置,各有所长了)
/WEB-INF/classes/ajf_sql_map.config


/**
 * zju ee && cs 
 * 国产偶像top3 毛泽东,邓小平,周恩来 
 * NBA偶像NO.1 Tim Duncan 
 * 头号足球偶像 罗纳尔多 
 * 小牛踏青 giscat@163.com 
**/


一个简单的例子


ajf_sql_map.config配置文件
支持//开头的单行注释

ajf_sql_map(q1)=select * from t_user

ajf_sql_map(q2)=select * from t_user where name like '%{name}%'

ajf_sql_map(q3)=select * from t_user where 2>1

        and name like '%{name}%' 

////ajf_sql_map(q1)=select * from t_user
///
/////ajf_sql_map(q1)=select * from t_user
///
   
   ajf_sql_map(q4)=select * from t_user    
       ajf_sql_map(q5)=select * from t_user    
       
       
       
测试代码

 Map map = JspUtil.getRequestModel(request);//把请求参数封装到map中
      List list = null;
      
      try{
      list = SqlMap.query("q1",map);
      out.println(list.size());
      }catch(Exception e){
      out.println(e);
      }
      
      try{
      list = SqlMap.query("q2",map);
      out.println(list.size());
      }catch(Exception e){
      out.println(e);
      }
      
      try{
      list = SqlMap.query("q3",map);
      out.println(list.size());
      }catch(Exception e){
      out.println(e);
      }
      
      try{
      list = SqlMap.query("q4",map);
      out.println(list.size());
      }catch(Exception e){
      out.println(e);
      }
      


SqlMap.java原代码


package com.zjuee;


import java.io.*;
import java.sql.*;
import java.util.*;
import java.util.regex.*;
//import org.apache.commons.beanutils.*;
import javax.servlet.*;
import javax.servlet.http.*;

/**
 * zju ee && cs 
 * 国产偶像top3 毛泽东,邓小平,周恩来 
 * NBA偶像NO.1 Tim Duncan 
 * 头号足球偶像 罗纳尔多 
 * 小牛踏青 giscat@163.com 
**/

public class SqlMap
{
    
    static Properties config = null;
    //static String sql_config_file = "/ajf_sql.properties";
    static String sql_config_file = "/ajf_sql_map.config";
    static Class c = SqlMap.class;
    static String SEP = "ajf_sql_map\\(";
    static String sql_config_string=null;
    
    
//------------
    private SqlMap()
    {
    }
    //clear the note,start with // ,single line
    //去掉注释,只支持以//开头的单行注释
    public static String getConfigString(String s)
    throws  Exception{
        
        if(s==null){return "";}
        s=s.replaceAll("//[^\\r\\n]{0,2000}[\\r\\n]{1,100}","");
        return s;
    }
    
    //参数替换,指定参数名

    public static String setParamSingle(String sql, String param, String v)
    throws Exception {

if (v == null)
    v = "";
if (param == null)
    param = "";
param = param.trim();
if (param.length() == 0)
    throw new Exception("\u53C2\u6570\u540D\u4E0D\u80FD\u4E3A\u7A7A");
String s = "{" + param + "}";
int ipos = 0;
int len = 0;
len = s.length();
String head = null;
String tail = null;
StringBuffer sql2 = new StringBuffer();
ipos = sql.indexOf(s);
tail = sql;
for (; ipos >= 0; ipos = sql.indexOf(s)) {
    head = sql.substring(0, ipos);
    tail = sql.substring(ipos + len);
    sql2.append(head).append(v);
    sql = tail;
}

sql2.append(tail);
return sql2.toString();

//return StringUtil.setParam(sql,param,v);
}

    
    
//--------------
    public    static Properties getSqlConfigProp()throws Exception{
        if(config!=null){return config;}
        return getSqlConfigPropInternal();
        
    }
    //读取配置文件
    //配置文件格式 ajf_sql_map(xxx)=select * from x   ,xxx表示sql name
    public  synchronized  static Properties getSqlConfigPropInternal()throws Exception{
        
        if(config!=null){return config;}
         InputStream is = null;
         InputStreamReader ir = null;
         StringBuffer sb = new StringBuffer();
         Properties prop = null;
         String msg = null;
         
         msg = "error when read ajf sql map config file [ WEB-INF/classes"+sql_config_file;
         msg=msg+" ],please check is it exist";
         //System.out.println("1");
         
         is = c.getResourceAsStream(sql_config_file);
        // System.out.println("2");
         if(is==null){
             
            
            throw new Exception(msg);
         }
        // if(is==null){System.out.println("is is null");}
         
         ir = new InputStreamReader(is);
         int ch = 0;
         
         if(ir==null){
             
             
             throw new Exception(msg);
          }
         
         ch = ir.read();
         
        // if(ir==null){System.out.println("ir is null");}
         
         while(ch>0){
            // System.out.println(ch);
             sb.append((char)ch);
             ch = ir.read();
             
         }
        
         String s = sb.toString();
         
         
         s=getConfigString(s);
         
         sql_config_string = s+"";
         //System.out.println(sql_config_string);
         int i =0;
         int num =0;
         String name = null;
         int pos = 0;
         int start = 0;
         int end = 0;
         String[]arr=null;
         String ss = null;
         String sql = null;
         arr=s.split(SEP);
         num=arr.length;
         prop = new Properties();
         for(i=0;i             
             ss=arr[i];
             pos = ss.indexOf(")=");
             if(pos<=0){continue;}
             name=ss.substring(0,pos);
             if(name==null){continue;}
             name=name.trim();
             if(name.length()<1){continue;}
             sql=ss.substring(pos+2);
             if(StringUtil.isempty(sql)){
                 continue;
             }
             sql=sql.trim();
             if(!StringUtil.isempty(prop.getProperty(name))){
                 throw new Exception("duplicate sql name["+name+"]");
             }
             prop.setProperty(name,sql);
             
         }
         
         
         return prop;
         
    }
    
    //获取所有参数 {xxx} xxx为参数名
    public static List getParamNames(String s) throws Exception {

        //List list = new ArrayList();
        List list = null;
        Map map = new HashMap();
        if (s == null) {
            return new ArrayList();
        }

        Pattern p = Pattern.compile("\\{([0-9A-Za-z._-]{0,50})\\}");
        Matcher m = p.matcher(s);
        String paramName = null;
        while (m.find()) {
            paramName = m.group(1);
            //list.add(paramName);
            map.put(paramName,"1");
        }

        //return list;
        return StringUtil.getMapKey(map);
    }
    
    //替换参数,全部替换
    public static String setParam(String s,  Map map)
    throws Exception {
if (map == null) {
    return s;
}
List list = getParamNames(s);
if (list == null) {

    return s;
}

int i = 0;
int num = 0;
String paramName = null;
String v = null;
Object obj = null;

num = list.size();
for (i = 0; i < num; i++) {
    paramName = (String) list.get(i);
    //System.out.println(paramName);
    obj = map.get(paramName);
    if(obj==null){
        v="";
        }else{
            v = obj+"";
        }
    
    //s = setParamSingle(s, paramName, (String)map.get(paramName));
    //System.out.println(v);
    //s = StringUtil.setParam(s, paramName, v);
    s = setParamSingle(s, paramName, v);
    //System.out.println(s);
}

return s;
}

    //根据 content 动态生成 sql
    //参数xxx不为空时,才输出 content,实现动态sql
    //目前只支持常见的notempty判断
    //可使用模板来动态生成sql语句,这样将非常强大,常见的模板工具有 freemark,velocity等
    //还是比较喜欢简单,就不使用第三方的模板工具了
    
    public static String getParamSql(String s,Map map)throws Exception{
        if(s==null){return "null";}
        if(map==null){return s;}
        
          String ps = "([^/]{1,500})";
          Pattern p = Pattern.compile(ps);
     Matcher m = p.matcher(s);
     StringBuffer sb = new StringBuffer();
     String v = null;
     String rs = null;
     String name = null;
  


     while (m.find()) {
      
            name=m.group(1);
            rs=m.group(2);
            v = (String)map.get(name);
        
            if(StringUtil.isempty(v)){
                 m.appendReplacement(sb, "");
             }else{
                      m.appendReplacement(sb, rs);
               
               }


     }
     m.appendTail(sb);
     return sb.toString();
        
    }
    
    //根据名称获取原始的sql语句
    
    public static String getSqlByName(String name)
    throws Exception{
        String s = null;
        if(StringUtil.isempty(name)){
            throw new Exception("sql name is empty");
        }
        s = getSqlConfigProp().getProperty(name);
        if(StringUtil.isempty(s)){
            throw new Exception("no sql names ["+name+"]");
        }
        return s;
        
    }
    //根据名称获取sql语句,动态生成,参数替换后的sql,可直接执行
    public static String getSqlByName(String name,Map map)
    throws Exception{
        String sql = null;
        
        sql = getSqlByName(name);
        
        sql=getParamSql(sql,map);
        if(map==null){return sql;}
        return getSql(sql,map);
        
        
    }
    
    
    public static String getSql(String s,Map map)throws Exception{
        if(map==null){return s;}
        if(map.isEmpty()){return s;}
        List list = getParamNames(s);
        return setParam(s,map);
    }
    
    //读取配置内容,文件内容 和 sql map 语句
    public static String getSqlConfigContent()throws Exception{
        String s = null;
        Properties prop = getSqlConfigProp();
        
        s=PropUtil.dump(prop)+"\n\n\n"+sql_config_string;
        
        return s;
    }
    
    
    //--------sql map jdbc 
    // executeUpdate不推荐使用
    
    public static int executeUpdate(Connection cn,
            String name,Map map)
    throws Exception{
        if(cn==null){
            throw new Exception("cn is null");
        }
        int num = 0;
        String sql = null;
        
        Statement stmt = null;
        
        sql = getSqlByName(name,map);
        //sql = getParamSql(sql,map);
        //getSql(sql,map);
        
        try{
        stmt = cn.createStatement();
        num = DBUtil.executeUpdate(stmt,sql);
        return num; 
        }catch(Exception e){
            throw new Exception(e+","+sql);
        }finally{DBUtil.close(stmt);}
        
             
    }
    
    public static int executeUpdate(
            String name,Map map)
    throws Exception{
        Connection cn = null;
        try{
        cn = DBUtil.getConn();
        return executeUpdate(cn,name,map);
        }catch(Exception e){
            throw e;
        }finally{
            DBUtil.close(cn);
        }
        }
    
    
    public static List query(Connection cn,
            String name,Map map)
    throws Exception{
        if(cn==null){
            throw new Exception("cn is null");
        }
    
        String sql = null;
        
        Statement stmt = null;
        ResultSet rs = null;
        
        
        sql = getSqlByName(name,map);
        //sql = getParamSql(sql,map);
        //getSql(sql,map);
        
        try{
        stmt = cn.createStatement();
        rs = DBUtil.executeQuery( stmt,sql);
        return DBUtil.rs2list(rs);//把resultSet 映射成map
               //rs2list代码见最后
               //支持结果集分页,参考 rs2list代码
        }catch(Exception e){
            throw new Exception(e+","+sql);
        }finally{
            DBUtil.close(rs);
            DBUtil.close(stmt);
            }
        
             
    }
    
    public static List query(
            String name,Map map)
    throws Exception{
        Connection cn = null;
        
        try{
            cn = DBUtil.getConn();
        return  query(cn,name,map);
        }catch(Exception e){
            throw e;
        }finally{
            DBUtil.close(cn);
        }
    }
    
    public static Map queryOne(Connection cn,String name,Map map)
    throws Exception{
        if(cn==null){
            throw new Exception("cn is null");
        }
    
        String sql = null;
        
        sql = getSqlByName(name,map);
        //sql = getParamSql(sql,map);
        
        //getSql(sql,map);
        return queryOne(cn, sql,null);
    }
    
    public static Map queryOne(String name,Map map)
    throws Exception{
Connection cn = null;
        
        try{
            cn = DBUtil.getConn();
        return  queryOne(cn,name,map);
        }catch(Exception e){
            throw e;
        }finally{
            DBUtil.close(cn);
        }
    }
    
    

}//end class








rs2list 相关代码


public static List rs2list(ResultSet rs) throws Exception {
        List list = new ArrayList();
        if (rs == null) {
            return list;
        }
        String[] arr = null;
        Map map = null;
        arr = getColName(rs);
        int i = 0;
        int num = 0;
        String v = null;
        if (arr != null) {
            num = arr.length;
            while (rs.next()) {
                map = new HashMap();
                for (i = 1; i <= num; i++) {
                    v = rs.getString(i);
                    if (v == null) {
                        v = "";
                    }
                    map.put(arr[i - 1], v);
                }// end for
                list.add(map);
            }// end while
        }// end if
        return list;
    }

//支持分页,基于结果集的通用"假"分页
//把结果集全部装载到内存,(数据量不大时完全可以这么做)
//对于大数据量查询,请设置statementset的setMaxRows参数,限制resultSet大小即可
//要不然会很慢且吃内存

public static List rs2list(ResultSet rs, int skip, int page_size)
            throws Exception {
        List list = new ArrayList();

        if (rs == null) {
            return list;
        }
        String[] arrColName = null;
        String colName = null;
        int colNum = 0;
        int pos = 0;
        int i = 0;
        int j = 0;
        Map map = null;
        String v = null;

        ResultSetMetaData rsmd = null;
        rsmd = rs.getMetaData();
        colNum = rsmd.getColumnCount();
        arrColName = new String[colNum];

        for (i = 1; i <= colNum; i++) {
            arrColName[i - 1] = rsmd.getColumnName(i).toLowerCase();
        }

        if (page_size == 0) {
            page_size = 10000000;
        }

        while ((rs.next()) && (j < page_size)) {

            if (pos < skip) {
                pos++;
                continue;
            }

            map = new HashMap();

            for (i = 0; i < colNum; i++) {
                v = rs.getString(i + 1);
                if (v == null) {
                    v = "";
                }
                map.put(arrColName[i], v);
            }

            j++;
            list.add(map);
        }// end while

        return list;

    }


public static String[] getColName(ResultSet rs) throws Exception {

        if (rs == null) {
            return null;
        }
        int num = 0;
        int i = 0;
        String colName = null;
        String[] arr = null;
        ResultSetMetaData rsmd = null;
        rsmd = rs.getMetaData();
        num = rsmd.getColumnCount();
        arr = new String[num];
        for (i = 1; i <= num; i++) {
            colName = rsmd.getColumnName(i);
            colName = colName.toLowerCase();
            arr[i - 1] = colName;
        }
        return arr;
    }
         (责任编辑:包春林)


[ 发表评论 ] 字体[  ] [ 打印 ] [ 进入博客 ] [ 进入论坛 ]  [ 推荐给朋友 ]
  相关文章
· visitor模式概念--- visitor模式进一步 (12-28) · JDK核心API:String.split()用法一点经验 (12-28)
· 测试:用FIT 集成测试框架进行确认测试 (12-28) · 数据库相关:hibernate O/R映射之基础 (12-28)
· Slt和Filter的url匹配及url-pattern详解 (12-28) · J2SE综合:浅谈java程序发布之 jre 篇 (12-28)
· J2SE综合--关于j2se的一些知识和技巧 (12-28) · 简单谈新手修练J2EE武功及学SSH的方法 (12-28)
· Java入门--java基础之api的零碎总结 (12-28) · 多线程设计模式:了解wait/notify机制 (12-28)
  客户需求反馈表
* 姓  名:
更多资料  了解方案  认识厂商
* 单位名称:
* 联系电话:
* 电子邮件:
  赛迪推荐  
  手机·资费 ·新品·导购·评测·手机资费·宽带
手机搜索  诺基亚 N73 MOTO Z6
  IT产品 ·笔记本·台式机·服务器·打印·投影
IT产品搜索 
  IT技术 ·开发·网管·安全·数据库·操作系统
  信息化 ·热点·专题·访谈·周刊·方案案例
· 信息化市场百家争鸣 SaaS深陷争议“泥潭”
· 提高管理水平 "两栖"CIO应具备的六大能力
· 国产ITIL运维先行者 四大厂商角力BI市场
· 金融行业GSN专题解决方案 企业网解决方案
  IT博客 ·曾剑秋·项立刚·Java学习·网管
  IT技术论坛 ·开发·网管·安全·数据库·系统