服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 开发工具 > 查看文档

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

超级简单的sqlmap工具

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

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

本工具特点:

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


    //根据 <notempty name="xxx">content</notempty> 动态生成 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

       <notempty name="name"> and name like '%{name}%' </notempty>

////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<num;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;
}

    //根据 <notempty name="xxx">content</notempty> 动态生成 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 = "<notempty[\\s]{1,100}name=\\\"([0-9a-za-z._-]{1,50})\\\">([^/]{1,500})</notempty>";
          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;
    }


以前也写的sqlmap可参考这里

http://www.javaresearch.org/article/50600.htm

          enjoy!
                                           giscat,2006.12.21 

扫描关注微信公众号