XMLScriptParser用来解析CRUD标签中的sql脚本

    1. package com.example.aninbatis.config;
    2. import com.example.aninbatis.sqlnode.IfSqlNode;
    3. import com.example.aninbatis.sqlnode.MixedSqlNode;
    4. import com.example.aninbatis.sqlnode.SqlNode;
    5. import com.example.aninbatis.sqlnode.StaticTextSqlNode;
    6. import com.example.aninbatis.sqlnode.TextSqlNode;
    7. import com.example.aninbatis.sqlnode.handler.NodeHandler;
    8. import com.example.aninbatis.sqlsource.DynamicSqlSource;
    9. import com.example.aninbatis.sqlsource.RawSqlSource;
    10. import com.example.aninbatis.sqlsource.SqlSource;
    11. import org.dom4j.Element;
    12. import org.dom4j.Node;
    13. import org.dom4j.Text;
    14. import java.util.ArrayList;
    15. import java.util.HashMap;
    16. import java.util.List;
    17. import java.util.Map;
    18. /**
    19. * 创建SqlSource其实就是对select等CRUD标签中的sql脚本进行处理
    20. */
    21. public class XMLScriptParser {
    22. /**
    23. * 标签以及对应的标签处理器
    24. */
    25. private Map<String, NodeHandler> nodeHandlerMap = new HashMap<>();
    26. private boolean isDynamic = false;
    27. public XMLScriptParser() {
    28. initNodeHandlerMap();
    29. }
    30. /**
    31. * 初始化标签处理器
    32. */
    33. private void initNodeHandlerMap() {
    34. nodeHandlerMap.put("if", new IfNodeHandler());
    35. // nodeHandlerMap.put("where", new WhereNodeHandler());
    36. // nodeHandlerMap.put("foreach", new ForeachNodeHandler());
    37. }
    38. public SqlSource parseScriptNode(Element selectElement) {
    39. // 首先先将sql脚本按照不同的类型,封装到不同的SqlNode
    40. MixedSqlNode rootSqlNode = parseDynamicTags(selectElement);
    41. // 再将SqlNode集合封装到SqlSource中
    42. SqlSource sqlSource = null;
    43. if (isDynamic) {
    44. sqlSource = new DynamicSqlSource(rootSqlNode);
    45. } else {
    46. sqlSource = new RawSqlSource(rootSqlNode);
    47. }
    48. // 由于带有#{}和${}、动态标签的sql处理方式不同,所以需要封装到不同的SqlSource中
    49. return sqlSource;
    50. }
    51. private MixedSqlNode parseDynamicTags(Element selectElement) {
    52. List<SqlNode> contents = new ArrayList<SqlNode>();
    53. int nodeCount = selectElement.nodeCount();
    54. for (int i = 0; i < nodeCount; i++) {
    55. Node node = selectElement.node(i);
    56. // 需要去区分select标签的子节点类型
    57. // 如果是文本类型则封装到TextSqlNode或者StaticTextSqlNode
    58. if (node instanceof Text) {
    59. String sqlText = node.getText().trim();
    60. if (sqlText == null || sqlText.equals("")) {
    61. continue;
    62. }
    63. TextSqlNode sqlNode = new TextSqlNode(sqlText);
    64. // 判断文本中是否带有${}
    65. if (sqlNode.isDynamic()) {
    66. contents.add(sqlNode);
    67. isDynamic = true;
    68. } else {
    69. contents.add(new StaticTextSqlNode(sqlText));
    70. }
    71. } else if (node instanceof Element) {// 则递归解析
    72. // 比如说if\where\foreach等动态sql子标签就需要在这处理
    73. // 根据标签名称,封装到不同的节点信息
    74. Element nodeToHandle = (Element) node;
    75. String nodeName = nodeToHandle.getName().toLowerCase();
    76. // 每一种动态标签都应该有相应的处理逻辑
    77. // if("if".equals(nodeName)){
    78. // NodeHandler nodeHandler =new IfNodeHandler();
    79. // nodeHandler.handleNode(nodeToHandle, contents);
    80. //}
    81. NodeHandler nodeHandler = nodeHandlerMap.get(nodeName);
    82. nodeHandler.handleNode(nodeToHandle, contents);
    83. isDynamic = true;
    84. }
    85. }
    86. return new MixedSqlNode(contents);
    87. }
    88. }