XMLScriptParser用来解析CRUD标签中的sql脚本
package com.example.aninbatis.config;
import com.example.aninbatis.sqlnode.IfSqlNode;
import com.example.aninbatis.sqlnode.MixedSqlNode;
import com.example.aninbatis.sqlnode.SqlNode;
import com.example.aninbatis.sqlnode.StaticTextSqlNode;
import com.example.aninbatis.sqlnode.TextSqlNode;
import com.example.aninbatis.sqlnode.handler.NodeHandler;
import com.example.aninbatis.sqlsource.DynamicSqlSource;
import com.example.aninbatis.sqlsource.RawSqlSource;
import com.example.aninbatis.sqlsource.SqlSource;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.Text;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 创建SqlSource其实就是对select等CRUD标签中的sql脚本进行处理
*/
public class XMLScriptParser {
/**
* 标签以及对应的标签处理器
*/
private Map<String, NodeHandler> nodeHandlerMap = new HashMap<>();
private boolean isDynamic = false;
public XMLScriptParser() {
initNodeHandlerMap();
}
/**
* 初始化标签处理器
*/
private void initNodeHandlerMap() {
nodeHandlerMap.put("if", new IfNodeHandler());
// nodeHandlerMap.put("where", new WhereNodeHandler());
// nodeHandlerMap.put("foreach", new ForeachNodeHandler());
}
public SqlSource parseScriptNode(Element selectElement) {
// 首先先将sql脚本按照不同的类型,封装到不同的SqlNode
MixedSqlNode rootSqlNode = parseDynamicTags(selectElement);
// 再将SqlNode集合封装到SqlSource中
SqlSource sqlSource = null;
if (isDynamic) {
sqlSource = new DynamicSqlSource(rootSqlNode);
} else {
sqlSource = new RawSqlSource(rootSqlNode);
}
// 由于带有#{}和${}、动态标签的sql处理方式不同,所以需要封装到不同的SqlSource中
return sqlSource;
}
private MixedSqlNode parseDynamicTags(Element selectElement) {
List<SqlNode> contents = new ArrayList<SqlNode>();
int nodeCount = selectElement.nodeCount();
for (int i = 0; i < nodeCount; i++) {
Node node = selectElement.node(i);
// 需要去区分select标签的子节点类型
// 如果是文本类型则封装到TextSqlNode或者StaticTextSqlNode
if (node instanceof Text) {
String sqlText = node.getText().trim();
if (sqlText == null || sqlText.equals("")) {
continue;
}
TextSqlNode sqlNode = new TextSqlNode(sqlText);
// 判断文本中是否带有${}
if (sqlNode.isDynamic()) {
contents.add(sqlNode);
isDynamic = true;
} else {
contents.add(new StaticTextSqlNode(sqlText));
}
} else if (node instanceof Element) {// 则递归解析
// 比如说if\where\foreach等动态sql子标签就需要在这处理
// 根据标签名称,封装到不同的节点信息
Element nodeToHandle = (Element) node;
String nodeName = nodeToHandle.getName().toLowerCase();
// 每一种动态标签都应该有相应的处理逻辑
// if("if".equals(nodeName)){
// NodeHandler nodeHandler =new IfNodeHandler();
// nodeHandler.handleNode(nodeToHandle, contents);
//}
NodeHandler nodeHandler = nodeHandlerMap.get(nodeName);
nodeHandler.handleNode(nodeToHandle, contents);
isDynamic = true;
}
}
return new MixedSqlNode(contents);
}
}