w3cdomsql使用说明:
1:只能解析xml文件
2:只能解析标签cfj、model、sql、java、js 五个标签(所有标签都是自定义,可以自行更改)
标签说明:cfj标签相当于mybatis中的mapping
model为模块 必须配置属性id
sql为对应的与数据库交互的sql配置 必须配置id
java表示配置的字符串将以java进行编译并返回结果(注:java 里面不能有反斜杠转义字符,循环最好只用while for循环只支持for in ,
也不支持++,+=,-+,--,等逻辑运算,其他海待测试)
js表示配置的字符串将以javasrcipt进行编译运算并返回结果 3.参数传递:参数传递方式:#{wyid}且只支持这种方式
4.优缺点:缺点1.由于是动态解析因此如果数据量大解析较慢,
2.java代码逻辑支持率不高尽量不要在内部写逻辑,
3.js代码逻辑支持率较高尽量采用js代码
优点:1.项目不用搭建mybatis框架
2.更改xml文件后不需要重启服务器,连前端都不需要重新刷新
3.所有东西都是自行定义,好理解便于维护,并且可适用于所有框架以及模块。
<?xml version="1.0" encoding="UTF-8" ?>
<!--xml文件示例 java 循环只支持while循环 for循环支持率不高 慎用-->
<cfj>
<model id="fbdw">
<sql id="fbdw_info">
select * from fbdw_info where 1=1
<java>
if(zjsl==3){
sql.append("and zjsl=3 and wyid=#{wyid} and wyid=#{wyid} and wyid= # { wyid }");
}else{
sql.append("and zjsl!=3 wyid=#{wyid} and wyid=#{wyid} and wyid= # { wyid }");
}
</java>
<js>
if(zjsl==3){
sql+="and zjsl='3' and wyid=#{wyid} and wyid=#{wyid} and wyid= # { wyid }";
}else{
sql+="and zjsl!='3' and wyid=#{wyid} and wyid=#{wyid} and wyid= # { wyid }";
}
</js>
</sql>
</model>
</cfj>
效果
package cfjsf.util.w3cdom;
import org.apache.commons.jexl2.Expression;
import org.apache.commons.jexl2.JexlContext;
import org.apache.commons.jexl2.JexlEngine;
import org.apache.commons.jexl2.MapContext;
import org.w3c.dom.*;import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.util.Map;/**
* Created by 常发均 on 2019/8/7.
* xml文件动态生成sql解析工具类(脱离于mabatis框架,更改xml文件后不需要重启服务器,并且支持内部java代码以及js代码以及逻辑运算)
*/
public class XmlDynamicParseToSql {
public static String xmlSql(File file,String modelId,String sqlId,Map<String,Object> params) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
//获得根元素结点
Element root = doc.getDocumentElement();
return parseGcgs(root,modelId,sqlId,params);
}
private static String parseGcgs(Element element,String modelId,String sqlId,Map<String,Object> params) throws Exception {
StringBuffer dtSql=new StringBuffer("");
parseElementGcgs(element, modelId,sqlId,dtSql,params);
return dtSql.toString();
}
private static void parseElementGcgs(Element element,String modelId,String sqlId,StringBuffer dtSql,Map<String,Object> params) throws Exception {
String tagName = element.getNodeName();
if(!(tagName.equals("cfj")||tagName.equals("java")||tagName.equals("js")||tagName.equals("model")||tagName.equals("sql"))){
throw new Exception("this targetName count no found!");
}
boolean flag=true;
if(tagName.equals("model")||tagName.equals("sql")){
flag=false;
}
NodeList children = element.getChildNodes();
//element元素的所有属性所构成的NamedNodeMap对象,需要对其进行判断
NamedNodeMap map = element.getAttributes();
//如果该元素存在属性
/*
* 后面已经有判断 主要是担心认为操作失误 且第一个节点就为目标节点 判断不到
* 因此再次采用多重判断
* */
if(null != map)
{
for(int i = 0; i < map.getLength(); i++)
{
//获得该元素的每一个属性
Attr attr = (Attr)map.item(i);
String attrName = attr.getName();
String attrValue = attr.getValue();
if(attrName.equals("id")){
if(tagName.equals("model")&&attrValue.equals(modelId)){
flag=true;
}else if(tagName.equals("sql")&&attrValue.equals(sqlId)){
flag=true;
}
}
}
}
if(flag){
for(int i = 0; i < children.getLength(); i++)
{
Node node = children.item(i);
int a=0;//默认a等于0 表示节点名称不为model与sql的节点需继续所有节点递归 a等于1表示还未找到目标节点需跳出循环继续寻找 a等于2 表示已找到目标节点
/*
* 判断是否找到当前所需节点 找到就结束循环
* */
if(node.getNodeName().equals("model")){
if(isMbNode((Element) node,"model",modelId)){
a=2;
}else{
a=1;
continue;
}
} else if(node.getNodeName().equals("sql")){
if(isMbNode((Element) node,"sql",sqlId)){
a=2;
}else{
a=1;
continue;
}
}
//获得结点的类型
short nodeType = node.getNodeType();
if(nodeType == Node.ELEMENT_NODE)
{
//递归出口
/*
* sql节点下只能含有java与js节点 方便解析
*
* */
if(tagName.equals("sql")){
if(node.getNodeName().equals("java")||node.getNodeName().equals("js")){
//是元素,继续递归
parseElementGcgs((Element)node,modelId,sqlId,dtSql,params);
}else{
throw new Exception("sql标签中只能含有java或者js标签!");
}
}
else{
parseElementGcgs((Element)node,modelId,sqlId,dtSql,params);
}
}
else if(nodeType == Node.TEXT_NODE)
{
//递归出口
if(tagName.equals("sql")){
dtSql.append(node.getNodeValue().trim());
dtSql.append(" ");
}
else if(tagName.equals("java")){
dtSql.append(dtjxJava(node.getNodeValue().trim(),params));
dtSql.append(" ");
}
else if(tagName.equals("js")){
dtSql.append(dtjxJs(node.getNodeValue().trim(), params));
dtSql.append(" ");
}
/*
* 替换掉所有的参数 参数方式采用#{}
* */
if(dtSql.toString().indexOf("#")>-1){
String[] arr=dtSql.toString().split("\\#");
String str="";
int length=dtSql.toString().length();
for(int j=arr.length-1;j>=1;j--){
length=length-arr[j].length()-1;
if(arr[j].indexOf("{")>-1&&arr[j].indexOf("}")>arr[j].indexOf("{")+1){
str=arr[j].substring(arr[j].indexOf("{")+1,arr[j].indexOf("}"));
if(params.containsKey(str.trim())){
dtSql.replace(length,length+arr[j].indexOf("}")+2,"'"+params.get(str.trim()).toString()+"'");
}else{
throw new Exception("找不到参数"+str.trim()+"!");
}
}
}
}
}
else if(nodeType == Node.COMMENT_NODE)
{
Comment comment = (Comment)node;
//注释内容
String data = comment.getData();
}
if(a==2){
break;
}
}
}
}
/*
* 将字符串通过java进行动态编译并返回计算结果
* 采用jexl进行解析
* */
private static String dtjxJava(String javaStr,Map<String,Object> params){
JexlEngine jexl=new JexlEngine();
JexlContext jc = new MapContext();
for(String key:params.keySet()){
jc.set(key,params.get(key));
}
jc.set("sql",new StringBuffer(""));
Expression e = jexl.createExpression(javaStr);
if(null==e.evaluate(jc)){
return "";
}else{
return jc.get("sql").toString().trim();
}
}
/*
* 将字符串通过javasricpt进行动态编译并返回计算结果
* */
private static String dtjxJs(String jsSr,Map<String,Object> params){
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");
for(String key:params.keySet()){
engine.put(key, params.get(key));
}
engine.put("sql","");
try {
engine.eval(jsSr);
return engine.get("sql").toString().trim();
} catch (ScriptException e) {
e.printStackTrace();
}
return "";
}
/*
* 判断id是否相同
* */
private static boolean isMbNode(Element node,String nodeName,String nodeValue) throws Exception {
if(node.getNodeName().equals(nodeName)){
NamedNodeMap idNodeMap = node.getAttributes();
if(null!=idNodeMap){
try {
Attr attr=(Attr)idNodeMap.getNamedItem("id");
if(attr.getValue().equals(nodeValue)){
return true;
}
}catch (Exception e){
throw new Exception("请对该节点配置id属性!");
}
}else{
throw new Exception("请对该节点配置id属性!");
}
}
return false;
}
}
java 动态解析返回报文 java动态解析xml
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
java 定义xml报文 java xml报文解析
了解XML什么是XML? XML是Extensibe Markup Language的缩写,即可扩展标记语言,是一种简单的数据存储语言,使用一系列简单的标记来描述结构化数据。XML的结构
java 定义xml报文 java xml 编程语言 XML