a00b297ef8a8cbf40b60639a5b46f742a1186282.svn-base 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. package org.jeecg.common.util.dynamic.db;
  2. import freemarker.cache.StringTemplateLoader;
  3. import freemarker.core.ParseException;
  4. import freemarker.template.Configuration;
  5. import freemarker.template.Template;
  6. import lombok.extern.slf4j.Slf4j;
  7. import org.apache.commons.lang3.StringUtils;
  8. import org.jeecgframework.codegenerate.generate.util.SimpleFormat;
  9. import java.io.StringWriter;
  10. import java.util.Map;
  11. import java.util.regex.Pattern;
  12. /**
  13. * @author 赵俊夫
  14. * @version V1.0
  15. * @Title:FreemarkerHelper
  16. * @description:Freemarker引擎协助类
  17. * @date Jul 5, 2013 2:58:29 PM
  18. */
  19. @Slf4j
  20. public class FreemarkerParseFactory {
  21. private static final String ENCODE = "utf-8";
  22. /**
  23. * 参数格式化工具类
  24. */
  25. private static final String MINI_DAO_FORMAT = "DaoFormat";
  26. /**
  27. * 文件缓存
  28. */
  29. private static final Configuration _tplConfig = new Configuration();
  30. /**
  31. * SQL 缓存
  32. */
  33. private static final Configuration _sqlConfig = new Configuration();
  34. private static StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
  35. // 使用内嵌的(?ms)打开单行和多行模式
  36. private final static Pattern p = Pattern
  37. .compile("(?ms)/\\*.*?\\*/|^\\s*//.*?$");
  38. static {
  39. _tplConfig.setClassForTemplateLoading(
  40. new FreemarkerParseFactory().getClass(), "/");
  41. _tplConfig.setNumberFormat("0.#####################");
  42. _sqlConfig.setTemplateLoader(stringTemplateLoader);
  43. _sqlConfig.setNumberFormat("0.#####################");
  44. //classic_compatible设置,解决报空指针错误
  45. _sqlConfig.setClassicCompatible(true);
  46. }
  47. /**
  48. * 判断模板是否存在
  49. *
  50. * @throws Exception
  51. */
  52. public static boolean isExistTemplate(String tplName) throws Exception {
  53. try {
  54. Template mytpl = _tplConfig.getTemplate(tplName, "UTF-8");
  55. if (mytpl == null) {
  56. return false;
  57. }
  58. } catch (Exception e) {
  59. //update-begin--Author:scott Date:20180320 for:解决问题 - 错误提示sql文件不存在,实际问题是sql freemarker用法错误-----
  60. if (e instanceof ParseException) {
  61. log.error(e.getMessage(), e.fillInStackTrace());
  62. throw new Exception(e);
  63. }
  64. log.debug("----isExistTemplate----" + e.toString());
  65. //update-end--Author:scott Date:20180320 for:解决问题 - 错误提示sql文件不存在,实际问题是sql freemarker用法错误------
  66. return false;
  67. }
  68. return true;
  69. }
  70. /**
  71. * 解析ftl模板
  72. *
  73. * @param tplName 模板名
  74. * @param paras 参数
  75. * @return
  76. */
  77. public static String parseTemplate(String tplName, Map<String, Object> paras) {
  78. try {
  79. log.debug(" minidao sql templdate : " + tplName);
  80. StringWriter swriter = new StringWriter();
  81. Template mytpl = _tplConfig.getTemplate(tplName, ENCODE);
  82. if (paras.containsKey(MINI_DAO_FORMAT)) {
  83. throw new RuntimeException("DaoFormat 是 minidao 保留关键字,不允许使用 ,请更改参数定义!");
  84. }
  85. paras.put(MINI_DAO_FORMAT, new SimpleFormat());
  86. mytpl.process(paras, swriter);
  87. String sql = getSqlText(swriter.toString());
  88. paras.remove(MINI_DAO_FORMAT);
  89. return sql;
  90. } catch (Exception e) {
  91. log.error(e.getMessage(), e.fillInStackTrace());
  92. log.error("发送一次的模板key:{ " + tplName + " }");
  93. //System.err.println(e.getMessage());
  94. //System.err.println("模板名:{ "+ tplName +" }");
  95. throw new RuntimeException("解析SQL模板异常");
  96. }
  97. }
  98. /**
  99. * 解析ftl
  100. *
  101. * @param tplContent 模板内容
  102. * @param paras 参数
  103. * @return String 模板解析后内容
  104. */
  105. public static String parseTemplateContent(String tplContent,
  106. Map<String, Object> paras) {
  107. try {
  108. StringWriter swriter = new StringWriter();
  109. if (stringTemplateLoader.findTemplateSource("sql_" + tplContent.hashCode()) == null) {
  110. stringTemplateLoader.putTemplate("sql_" + tplContent.hashCode(), tplContent);
  111. }
  112. Template mytpl = _sqlConfig.getTemplate("sql_" + tplContent.hashCode(), ENCODE);
  113. if (paras.containsKey(MINI_DAO_FORMAT)) {
  114. throw new RuntimeException("DaoFormat 是 minidao 保留关键字,不允许使用 ,请更改参数定义!");
  115. }
  116. paras.put(MINI_DAO_FORMAT, new SimpleFormat());
  117. mytpl.process(paras, swriter);
  118. String sql = getSqlText(swriter.toString());
  119. paras.remove(MINI_DAO_FORMAT);
  120. return sql;
  121. } catch (Exception e) {
  122. log.error(e.getMessage(), e.fillInStackTrace());
  123. log.error("发送一次的模板key:{ " + tplContent + " }");
  124. //System.err.println(e.getMessage());
  125. //System.err.println("模板内容:{ "+ tplContent +" }");
  126. throw new RuntimeException("解析SQL模板异常");
  127. }
  128. }
  129. /**
  130. * 除去无效字段,去掉注释 不然批量处理可能报错 去除无效的等于
  131. */
  132. private static String getSqlText(String sql) {
  133. // 将注释替换成""
  134. sql = p.matcher(sql).replaceAll("");
  135. sql = sql.replaceAll("\\n", " ").replaceAll("\\t", " ")
  136. .replaceAll("\\s{1,}", " ").trim();
  137. // 去掉 最后是 where这样的问题
  138. if (sql.endsWith("where") || sql.endsWith("where ")) {
  139. sql = sql.substring(0, sql.lastIndexOf("where"));
  140. }
  141. // 去掉where and 这样的问题
  142. int index = 0;
  143. while ((index = StringUtils.indexOfIgnoreCase(sql, "where and", index)) != -1) {
  144. sql = sql.substring(0, index + 5)
  145. + sql.substring(index + 9, sql.length());
  146. }
  147. // 去掉 , where 这样的问题
  148. index = 0;
  149. while ((index = StringUtils.indexOfIgnoreCase(sql, ", where", index)) != -1) {
  150. sql = sql.substring(0, index)
  151. + sql.substring(index + 1, sql.length());
  152. }
  153. // 去掉 最后是 ,这样的问题
  154. if (sql.endsWith(",") || sql.endsWith(", ")) {
  155. sql = sql.substring(0, sql.lastIndexOf(","));
  156. }
  157. return sql;
  158. }
  159. }