精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-12-22
最后修改:2009-08-26
与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 一个简单的例子 ajf_sql_map.config配置文件 支持//开头的单行注释 如果sql name 重名,读取配置文件时会报错 throw new Exception("duplicate sql name["+name+"]"); 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 javax.servlet.*; //import javax.servlet.http.*; /** * 小牛踏青 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; } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2006-12-22
已经包含源代码,不算多的把
|
|
返回顶楼 | |
发表时间:2006-12-31
给打个包吧
|
|
返回顶楼 | |
发表时间:2006-12-31
支持楼主,用起来蛮简单的,跟Ibatis很像:),佩服!
|
|
返回顶楼 | |
发表时间:2006-12-31
不知道好坏,无权评论
只是看到代码的风格就有一些不太想看下去了 |
|
返回顶楼 | |
发表时间:2006-12-31
LS算是说到俺们心坎里去了
|
|
返回顶楼 | |
发表时间:2006-12-31
对ORM现在没有太大兴趣了。像我门系统表一般都有一百多张表,业务复杂,大多是多表关联。没有太多价值。还影响速度。
|
|
返回顶楼 | |
发表时间:2006-12-31
ORM确实有其局限性,业务复杂,关联超过3层的不建议使用, (业务模型过于复杂,可能是分析设计做的不到位,从这个层面上讲, 使用hibernate可以驱动良好严谨的设计 这个要考验分析设计人员的功力, 上层设计不过关,下面的coding就有得不爽了 ) 不过很多时候业务就是这么复杂,ORM处理颇为费劲吃力, 那就直接上sql了, 这时sqlmap便派上用场了,把sql放到xml文件里 避免在程序里硬编码,可以轻松维护,调优 还可以轻松跨数据库,只要写多套xml配置文件即可 sqlmap在处理复杂查询时更显得简单经济实惠 |
|
返回顶楼 | |
发表时间:2007-03-13
public List divPage(final String b_hql,final String a_hql,Map params, DivPage divPage){ String hql_count = "select count(*) " + a_hql; String hql_query = b_hql+a_hql; Session session = null; List result = null; AppLog.message("...............divPage................."+b_hql+" "+a_hql); try { session = getSession(true); Query query_count = session.createQuery(hql_count); Query query = session.createQuery(hql_query); for(Iterator it = params.keySet().iterator(); it.hasNext();){ String key = (String)it.next(); String value = (String)params.get(key); query_count.setParameter(key, value); query.setParameter(key, value); } query.setFirstResult(divPage.getFirstResult()); query.setMaxResults(divPage.getPageRows()); divPage.setSize(Integer.parseInt(query_count.uniqueResult().toString())); result = query.list(); } catch (Exception e) { AppLog.error(module, e.getMessage()); e.printStackTrace(); } finally { this.colseSession(session); } return result; } |
|
返回顶楼 | |
发表时间:2007-03-13
melin 写道 对ORM现在没有太大兴趣了。像我门系统表一般都有一百多张表,业务复杂,大多是多表关联。没有太多价值。还影响速度。
用了ORM,就会喜欢上他 |
|
返回顶楼 | |