|
18 | 18 | import java.sql.SQLSyntaxErrorException;
|
19 | 19 | import java.util.HashMap;
|
20 | 20 | import java.util.Map;
|
| 21 | +import java.util.regex.Matcher; |
| 22 | +import java.util.regex.Pattern; |
| 23 | + |
| 24 | +import org.springframework.jdbc.BadSqlGrammarException; |
21 | 25 |
|
22 | 26 | import net.paoding.rose.jade.statement.expression.ExqlPattern;
|
23 | 27 | import net.paoding.rose.jade.statement.expression.impl.ExqlContextImpl;
|
24 | 28 | import net.paoding.rose.jade.statement.expression.impl.ExqlPatternImpl;
|
25 | 29 |
|
26 |
| -import org.springframework.jdbc.BadSqlGrammarException; |
27 |
| - |
28 | 30 | /**
|
29 | 31 | *
|
30 | 32 | * @author 廖涵 [in355hz@gmail.com]
|
31 | 33 | */
|
32 | 34 | public class SystemInterpreter implements Interpreter {
|
33 | 35 |
|
| 36 | + private ReplacementInterpreter replacementInterpreter = new ReplacementInterpreter(); |
| 37 | + private PreparestatmentInterpreter preparestatmentInterpreter = new PreparestatmentInterpreter(); |
| 38 | + |
34 | 39 | @Override
|
35 | 40 | public void interpret(StatementRuntime runtime) {
|
36 |
| - // 转换语句中的表达式 |
37 |
| - ExqlPattern pattern = ExqlPatternImpl.compile(runtime.getSQL()); |
38 |
| - ExqlContextImpl context = new ExqlContextImpl(runtime.getSQL().length() + 32); |
39 |
| - |
40 |
| - try { |
41 |
| - pattern.execute(context, runtime.getParameters(), runtime.getMetaData() |
42 |
| - .getDAOMetaData().getConstants()); |
43 |
| - runtime.setArgs(context.getParams()); |
44 |
| - runtime.setSQL(context.flushOut()); |
45 |
| - } catch (Exception e) { |
46 |
| - String daoInfo = runtime.getMetaData().toString(); |
47 |
| - throw new BadSqlGrammarException(daoInfo, runtime.getSQL(), |
| 41 | + replacementInterpreter.interpret(runtime); |
| 42 | + preparestatmentInterpreter.interpret(runtime); |
| 43 | + } |
| 44 | + |
| 45 | + /** |
| 46 | + * 使用方法参数、常量替换{xxxx}、{:xxxx}、##(:xxx)、##(xxx)等位置; |
| 47 | + * <p> |
| 48 | + * |
| 49 | + * select form ##(:table) {name} where {id}='{1}' |
| 50 | + * @author zlw |
| 51 | + * |
| 52 | + */ |
| 53 | + static class ReplacementInterpreter implements Interpreter { |
| 54 | + |
| 55 | + final Pattern PATTERN = Pattern.compile("\\{([a-zA-Z0-9_\\.\\:]+)\\}|##\\((.+)\\)"); |
| 56 | + |
| 57 | + @Override |
| 58 | + public void interpret(StatementRuntime runtime) {// ##(:xxx) |
| 59 | + String sql = runtime.getSQL(); |
| 60 | + StringBuilder sb = new StringBuilder(sql.length() + 200); |
| 61 | + Matcher matcher = PATTERN.matcher(sql); |
| 62 | + int start = 0; |
| 63 | + while (matcher.find(start)) { |
| 64 | + sb.append(sql.substring(start, matcher.start())); |
| 65 | + String group = matcher.group(); |
| 66 | + String key = null; |
| 67 | + if (group.startsWith("{")) { |
| 68 | + key = matcher.group(1); |
| 69 | + } else if (group.startsWith("##(")) { |
| 70 | + key = matcher.group(2); |
| 71 | + } |
| 72 | + // get value from parameters |
| 73 | + Object value = runtime.getParameters().get(key); // 针对{paramName}、{:1}两种情况 |
| 74 | + if (value == null) { |
| 75 | + if (key.startsWith(":") || key.startsWith("$")) { |
| 76 | + value = runtime.getParameters().get(key.substring(1)); // 针对{:paramName}的情况 |
| 77 | + } else { |
| 78 | + char ch = key.charAt(0);// 由正则表达式知道key长度必定大于0 |
| 79 | + if (ch >= '0' && ch <= '9') { |
| 80 | + value = runtime.getParameters().get(":" + key); // 针对{1}两种情况 |
| 81 | + } |
| 82 | + } |
| 83 | + } |
| 84 | + // get value from constants |
| 85 | + if (value == null) { |
| 86 | + value = runtime.getMetaData().getDAOMetaData().getConstants().get(key); // 针对常量的情况 |
| 87 | + } |
| 88 | + // get value from attributes |
| 89 | + if (value == null) { |
| 90 | + String attributeKey = group; |
| 91 | + if (!attributeKey.startsWith("{")) { |
| 92 | + attributeKey = "{" + key + "}"; |
| 93 | + } |
| 94 | + value = runtime.getMetaData().getDAOMetaData().getAttribute(attributeKey); // 针对插件设置进来的属性的情况 |
| 95 | + } |
| 96 | + // replace it |
| 97 | + if (value != null) { |
| 98 | + sb.append(value); |
| 99 | + } else { |
| 100 | + sb.append(group); |
| 101 | + } |
| 102 | + start = matcher.end(); |
| 103 | + } |
| 104 | + sb.append(sql.substring(start)); |
| 105 | + |
| 106 | + runtime.setSQL(sb.toString()); |
| 107 | + |
| 108 | + } |
| 109 | + } |
| 110 | + |
| 111 | + // 动态参数 |
| 112 | + static class PreparestatmentInterpreter implements Interpreter { |
| 113 | + |
| 114 | + @Override |
| 115 | + public void interpret(StatementRuntime runtime) { |
| 116 | + // 转换语句中的表达式 |
| 117 | + ExqlPattern pattern = ExqlPatternImpl.compile(runtime.getSQL()); |
| 118 | + ExqlContextImpl context = new ExqlContextImpl(runtime.getSQL().length() + 32); |
| 119 | + |
| 120 | + try { |
| 121 | + Map<String, Object> constants = runtime.getMetaData().getDAOMetaData() |
| 122 | + .getConstants(); |
| 123 | + pattern.execute(context, runtime.getParameters(), constants); |
| 124 | + runtime.setArgs(context.getArgs()); |
| 125 | + runtime.setSQL(context.flushOut()); |
| 126 | + } catch (Exception e) { |
| 127 | + String daoInfo = runtime.getMetaData().toString(); |
| 128 | + throw new BadSqlGrammarException(daoInfo, runtime.getSQL(), |
48 | 129 | new SQLSyntaxErrorException(daoInfo + " @SQL('" + runtime.getSQL() + "')", e));
|
| 130 | + } |
49 | 131 | }
|
50 | 132 |
|
51 | 133 | }
|
52 | 134 |
|
| 135 | + // ReplacementInterpreter |
53 | 136 | public static void main(String[] args) throws Exception {
|
| 137 | + Map<String, Object> parameters = new HashMap<String, Object>(); |
| 138 | + parameters.put("table", "my_table_name"); |
| 139 | + parameters.put("id", "my_id"); |
| 140 | + parameters.put(":1", "first_param"); |
| 141 | + |
| 142 | + final Pattern PATTERN = Pattern.compile("\\{([a-zA-Z0-9_\\.\\:]+)\\}|##\\((.+)\\)"); |
| 143 | + |
| 144 | + String sql = "select form ##(:table) {name} where {id}='{1}'"; |
| 145 | + |
| 146 | + StringBuilder sb = new StringBuilder(sql.length() + 200); |
| 147 | + Matcher matcher = PATTERN.matcher(sql); |
| 148 | + int start = 0; |
| 149 | + while (matcher.find(start)) { |
| 150 | + sb.append(sql.substring(start, matcher.start())); |
| 151 | + String group = matcher.group(); |
| 152 | + String key = null; |
| 153 | + if (group.startsWith("{")) { |
| 154 | + key = matcher.group(1); |
| 155 | + } else if (group.startsWith("##(")) { |
| 156 | + key = matcher.group(2); |
| 157 | + } |
| 158 | + System.out.println(key); |
| 159 | + if (key == null || key.length() == 0) { |
| 160 | + continue; |
| 161 | + } |
| 162 | + Object value = parameters.get(key); // 针对{paramName}、{:1}两种情况 |
| 163 | + if (value == null) { |
| 164 | + if (key.startsWith(":") || key.startsWith("$")) { |
| 165 | + value = parameters.get(key.substring(1)); // 针对{:paramName}的情况 |
| 166 | + } else { |
| 167 | + char ch = key.charAt(0); |
| 168 | + if (ch >= '0' && ch <= '9') { |
| 169 | + value = parameters.get(":" + key); // 针对{1}两种情况 |
| 170 | + } |
| 171 | + } |
| 172 | + } |
| 173 | + if (value == null) { |
| 174 | + value = parameters.get(key); // 针对常量的情况 |
| 175 | + } |
| 176 | + if (value != null) { |
| 177 | + sb.append(value); |
| 178 | + } else { |
| 179 | + sb.append(group); |
| 180 | + } |
| 181 | + start = matcher.end(); |
| 182 | + } |
| 183 | + sb.append(sql.substring(start)); |
| 184 | + System.out.println(sb); |
| 185 | + |
| 186 | + } |
| 187 | + |
| 188 | + // ExqlInterpreter |
| 189 | + public static void main0(String[] args) throws Exception { |
54 | 190 | // 转换语句中的表达式
|
55 | 191 | String sql = "insert ignore into table_name "
|
56 |
| - + "(`id`,`uid`,`favable_id`,`addtime`,`ranking`) "// |
57 |
| - + "values (:1,:2,now(),0)"; |
| 192 | + + "(`id`,`uid`,`favable_id`,`addtime`,`ranking`) "// |
| 193 | + + "values (:1,:2,now(),0)"; |
58 | 194 | ExqlPattern pattern = ExqlPatternImpl.compile(sql);
|
59 | 195 | ExqlContextImpl context = new ExqlContextImpl(sql.length() + 32);
|
60 | 196 |
|
61 | 197 | Map<String, Object> parametersAsMap = new HashMap<String, Object>();
|
62 | 198 | parametersAsMap.put(":1", "p1");
|
63 | 199 | parametersAsMap.put(":2", "p2");
|
64 | 200 |
|
65 |
| - String result = pattern.execute(context, parametersAsMap); |
| 201 | + pattern.execute(context, parametersAsMap); |
| 202 | + String result = context.flushOut(); |
66 | 203 | System.out.println(result);
|
67 | 204 | }
|
68 | 205 |
|
|
0 commit comments