暂不支持嵌套标签):
import java.io.File; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; /** * * @description SQL动态解析 * @author 杨惠 * @version 1.0 * @date 2013-5-10 */ public class SqlParse { private static Logger logger = Logger.getLogger(SqlParse.class); private String encoding = "UTF-8"; private SAXReader saxReader = null; private Document document = null; // XML文件全路径 private String filePath = "D:\\sql.xml"; public SqlParse() { Init(); } public SqlParse(String filePath) { this.filePath = filePath; Init(); } /** * 初始化 */ private void Init() { File file = new File(filePath); if (file.exists() && file.isFile()) { try { saxReader = new SAXReader(); document = saxReader.read(file); } catch (Exception e) { logger.error(e); document = null; } finally { saxReader = null; file = null; } } else { logger.error("指定文件不存在;"); } } /** * 根据传入参数Map,动态替换SQL标签,解析成最终执行的SQL语句 * * @param selectID * select元素的ID * @param mapPara * SQL参数 * @return * @throws Exception */ @SuppressWarnings("unchecked") public final Map<String, String> parseSql(String strID, Map<String, String> mapPara) throws Exception { // 1.根据sqlID获得SQL语句元素 Element elementParent = (Element) document .selectSingleNode("//select[@id='" + strID + "'] "); if (elementParent == null) { logger.info("文件名:" + filePath + ";信息:无id=" + strID + "的元素。"); return null; } if (mapPara == null) { mapPara = new HashMap<String, String>(); } // 2.解析每一个子元素标签,例如isNotEmpty,isEqual等 List<Element> listElements = elementParent.elements(); if (listElements != null && (!listElements.isEmpty())) { for (Element element : listElements) { parseElement(element, mapPara); } } // 3.解析SQL,用Map值替换SQL标签 String strSQL = elementParent.getStringValue(); Set<String> setKey = mapPara.keySet(); String strProperty = null; for (Iterator<String> iterator = setKey.iterator(); iterator.hasNext();) { strProperty = (String) iterator.next(); strSQL = strSQL.replaceAll("#" + strProperty + "#", mapPara.get(strProperty)); strProperty = null; } Map<String, String> mapSQL = new HashMap<String, String>(); mapSQL.put("sqlText", strSQL.replaceAll("\\s{2,}", " ")); List<Attribute> listAttribute = elementParent.attributes(); for (Attribute attribute : listAttribute) { mapSQL.put(attribute.getName(), attribute.getText()); } // 4.释放变量 strID = null; mapPara = null; elementParent = null; listElements = null; setKey = null; strSQL = null; return mapSQL; } /** * 解析每一个标签元素 * * @param element * 标签元素 * @param mapPara * SQL参数 * @throws Exception */ private final void parseElement(Element element, Map<String, String> mapPara) throws Exception { // 获得节点名称、属性,属性值 String strElementName = element.getName(); String strProperty = element.attributeValue("property").trim(); String strPropertyValue = mapPara.get(strProperty); // 是否删除该节点 boolean booDelete = false; // 标签处理 if (StringUtils.equals(strElementName, "isNotEmpty")) { // 是否非空 if (StringUtils.isBlank(strPropertyValue)) { booDelete = true; } } else if (StringUtils.equals(strElementName, "isEmpty")) { // 是否为空 if (StringUtils.isNotBlank(strPropertyValue)) { booDelete = true; } } else { // 比较值 if (StringUtils.isBlank(strPropertyValue)) { booDelete = true; } else { double douPropertyValue = Double.parseDouble(strPropertyValue); double douCompareValue = Double.parseDouble(element .attributeValue("compareValue").trim()); if (StringUtils.equals(strElementName, "isGreaterThan")) { // 是否大于 if (douPropertyValue <= douCompareValue) { booDelete = true; } } else if (StringUtils.equals(strElementName, "isGreaterEqual")) { // 是否大于等于 if (douPropertyValue < douCompareValue) { booDelete = true; } } else if (StringUtils.equals(strElementName, "isLessThan")) { // 是否小于 if (douPropertyValue >= douCompareValue) { booDelete = true; } } else if (StringUtils.equals(strElementName, "isEqual")) { // 是否等于 if (douPropertyValue != douCompareValue) { booDelete = true; } } else if (StringUtils.equals(strElementName, "isNotEqual")) { // 是否不等于 if (douPropertyValue == douCompareValue) { booDelete = true; } } else if (StringUtils.equals(strElementName, "isLessEqual")) { // 是否小于等于 if (douPropertyValue > douCompareValue) { booDelete = true; } } } } if (booDelete == true) { element.getParent().remove(element); } // 释放变量 element = null; mapPara = null; strElementName = null; strProperty = null; strPropertyValue = null; } /** * 获得:XML文件编码 * * @return the encoding */ public final String getEncoding() { return encoding; } /** * 设置:XML文件编码 * * @param encoding * the encoding to set */ public final void setEncoding(String encoding) { if (encoding != null) { this.encoding = encoding; } } /** * 获得:Document * * @return the document */ public final Document getDocument() { return document; } /** * 设置:Document * * @param document * the document to set */ public final void setDocument(Document document) { if (document != null) { this.document = document; } } /** * 获得:XMl文件全路径(含文件名) * * @return the filePath */ public final String getFilePath() { return filePath; } /** * 设置:XMl文件全路径(含文件名) * * @param filePath * the filePath to set */ public final void setFilePath(String filePath) { if (filePath != null) { this.filePath = filePath; } } public static void main(String[] args) { try { Map<String, String> mapPara = new HashMap<String, String>(); mapPara.put("menucode", "sysAdmin"); SqlParse sqlParse = new SqlParse("d:/sql.xml"); System.out.println(sqlParse.parseSql( "queryMenuAsList", mapPara)); } catch (Exception e) { e.printStackTrace(); } } }
上面main方法打印结果:
{id=queryMenuAsList, name=菜单表, sqlText= select menucode as 菜单编码,menuname as 菜单名称 from tb_upc_menu where 1=1 and menucode='myWork' }
Sql.xml:
<?xml version="1.0" encoding="UTF-8"?> <root> <select id="queryMenuAsList" name="菜单表"> select menucode as 菜单编码,menuname as 菜单名称 from tb_upc_menu where 1=1 <isNotEmpty property="menucode"> and menucode='myWork' </isNotEmpty> </select> <select id="queryUserAsList" name="用户表"> select row_number() OVER( order by createtime desc) as 序号,usercode as ID,username as 名称,mobile as 手机号 from tb_upc_user </select> </root>