Mybatis生成器插件扩展,生成findInSet方法

梦里梦外; 2022-12-26 14:27 317阅读 0赞

Mybatis生成器插件扩展,生成findInSet方法

  1. public Criteria andNameFindInSet(String value) {
  2. addCriterionPattern("find_in_set($value, `name`)", value, "name");
  3. return (Criteria) this;
  4. }
  5. public Criteria andNamePattern(String pattern, String value) {
  6. addCriterionPattern(pattern.replace("##column##", "`name`"), value, "name");
  7. return (Criteria) this;
  8. }

一、生成模式原理

(1)Example.Criterion添加pattern字段

  1. public static class Criterion {
  2. private String condition;
  3. private Object value;
  4. private Object secondValue;
  5. private boolean noValue;
  6. private boolean singleValue;
  7. private boolean betweenValue;
  8. private boolean listValue;
  9. private String typeHandler;
  10. private boolean pattern;
  11. }

(2)Example.GeneratedCriteria加方法addCriterionPattern

  1. protected abstract static class GeneratedCriteria
  2. protected void addCriterionPattern(String condition, Object value, String property) {
  3. if (value == null) {
  4. throw new RuntimeException("Value for " + property + " cannot be null");
  5. }
  6. Criterion c = new Criterion(condition, value);
  7. c.setPattern(true);
  8. criteria.add(c);
  9. }
  10. }

(3) 加对应列FindInSet方法

  1. protected abstract static class GeneratedCriteria {
  2. public Criteria andXXXFindInSet(String value) {
  3. addCriterionPattern("find_in_set(##value##, `xxx`)", value, "xxx");
  4. return (Criteria) this;
  5. }
  6. }

(4)改造XXXSqlProvider.applyWhere的 if (criterion.isNoValue()) 前增加模式代码

  1. if (criterion.isPattern()) {
  2. String value;
  3. if (criterion.getTypeHandler() == null) {
  4. value = String.format(parmPhrase1, "", i, j).trim();
  5. } else {
  6. value = String.format(parmPhrase1_th, "", i, j, criterion.getTypeHandler()).trim();
  7. }
  8. sb.append(criterion.getCondition().replaceAll("##value##", value));
  9. } else if (criterion.isNoValue()) {
  10. sb.append(criterion.getCondition());
  11. } else if (criterion.isSingleValue()) {
  12. }

(5)改造XXXMapper.xml的前增加模式代码

  1. <when test="criterion.pattern">
  2. and
  3. <foreach collection="criterion.condition.split('##value##')" item="criterionCond" separator="#{criterion.value}">
  4. ${criterionCond}
  5. </foreach>
  6. </when>
  7. <when test="criterion.noValue">
  8. and ${criterion.condition}
  9. </when>

二、插件代码

  1. package com.mk.mybatisgenerator.plugins;
  2. import org.mybatis.generator.api.IntrospectedColumn;
  3. import org.mybatis.generator.api.IntrospectedTable;
  4. import org.mybatis.generator.api.PluginAdapter;
  5. import org.mybatis.generator.api.dom.java.*;
  6. import org.mybatis.generator.api.dom.xml.Attribute;
  7. import org.mybatis.generator.api.dom.xml.Element;
  8. import org.mybatis.generator.api.dom.xml.TextElement;
  9. import org.mybatis.generator.api.dom.xml.XmlElement;
  10. import org.mybatis.generator.codegen.ibatis2.Ibatis2FormattingUtilities;
  11. import java.util.ArrayList;
  12. import java.util.List;
  13. public class MySQLMethodPlugin extends PluginAdapter {
  14. private final String valueName = "##value##";//值占位符
  15. private final String columnName = "##column##";//列名占位符
  16. public MySQLMethodPlugin() {
  17. super();
  18. }
  19. @Override
  20. public boolean validate(List<String> warnings) {
  21. return true;
  22. }
  23. /**
  24. * 重写example
  25. * @param topLevelClass
  26. * @param introspectedTable
  27. * @return
  28. */
  29. @Override
  30. public boolean modelExampleClassGenerated(TopLevelClass topLevelClass,
  31. IntrospectedTable introspectedTable) {
  32. addCriterionPattern(topLevelClass, introspectedTable);//增加模式匹配
  33. addFindInSet(topLevelClass, introspectedTable);//增加find_in_set方法
  34. addPattern(topLevelClass, introspectedTable);//增加模式方法
  35. return true;
  36. }
  37. /**
  38. * xml ExampleWhere重写
  39. * @param element
  40. * @param introspectedTable
  41. * @return
  42. */
  43. @Override
  44. public boolean sqlMapExampleWhereClauseElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
  45. XmlElement whereElement = (XmlElement) element.getElements().get(0);
  46. XmlElement foreachElement = (XmlElement) whereElement.getElements().get(0);
  47. XmlElement ifElement = (XmlElement) foreachElement.getElements().get(0);
  48. XmlElement trimElement = (XmlElement) ifElement.getElements().get(0);
  49. XmlElement foreachCriteriaElement = (XmlElement) trimElement.getElements().get(0);
  50. XmlElement chooseElement = (XmlElement) foreachCriteriaElement.getElements().get(0);
  51. for (Element ele : chooseElement.getElements()) {
  52. XmlElement noValueElement = (XmlElement) ele;
  53. for (Attribute attribute : noValueElement.getAttributes()) {
  54. //找到criterion.noValue行插入模式代码
  55. if (attribute.getName().equals("test") && attribute.getValue().equals("criterion.noValue")) {
  56. XmlElement patternElement = new XmlElement("when");
  57. patternElement.addAttribute(new Attribute("test", "criterion.pattern"));
  58. //<foreach collection="oredCriteria" item="criteria" separator="or">
  59. XmlElement forElement = new XmlElement("foreach");
  60. forElement.addAttribute(new Attribute("collection", "criterion.condition.split('" + valueName + "')"));
  61. forElement.addAttribute(new Attribute("item", "criterionCond"));
  62. forElement.addAttribute(new Attribute("separator", "#{criterion.value}"));
  63. forElement.addElement(new TextElement("${criterionCond}"));
  64. patternElement.addElement(new TextElement("and"));
  65. patternElement.addElement(forElement);
  66. chooseElement.addElement(0, patternElement);
  67. return true;
  68. }
  69. }
  70. }
  71. throw new RuntimeException("ChooseElement not exist");
  72. }
  73. /**
  74. * 重写ApplyWhere方法
  75. * @param method
  76. * @param topLevelClass
  77. * @param introspectedTable
  78. * @return
  79. */
  80. @Override
  81. public boolean providerApplyWhereMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
  82. List<String> lines = method.getBodyLines();
  83. for (int i = 0, len = lines.size(); i < len; i++) {
  84. String line = lines.get(i).trim();
  85. //找到criterion.noValue行插入模式代码
  86. if (line.matches("if\\s*\\(criterion\\.isNoValue\\(\\)\\)\\s*\\{")) {
  87. lines.remove(i);
  88. List<String> appends = new ArrayList<>();
  89. appends.add("if (criterion.isPattern()) {");
  90. appends.add("String value;");
  91. appends.add(" if (criterion.getTypeHandler() == null) {");
  92. appends.add("value = String.format(parmPhrase1, \"\", i, j).trim();");
  93. appends.add("} else {");
  94. appends.add("value = String.format(parmPhrase1_th, \"\", i, j, criterion.getTypeHandler()).trim();");
  95. appends.add("}");
  96. appends.add("sb.append(criterion.getCondition().replaceAll(\"" + valueName + "\", value));");
  97. appends.add("} else " + line);
  98. method.addBodyLines(i, appends);
  99. return true;
  100. }
  101. }
  102. throw new RuntimeException("criterion.isNoValue() not exist");
  103. }
  104. /*
  105. protected void addCriterionPattern(String condition, Object value, String property) {
  106. if (value == null) {
  107. throw new RuntimeException("Value for " + property + " cannot be null");
  108. }
  109. Criterion c = new Criterion(condition, value);
  110. c.setPattern(true);
  111. criteria.add(c);
  112. }
  113. */
  114. public void addCriterionPattern(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
  115. addCriterionPatternField(topLevelClass, introspectedTable);
  116. InnerClass criteria = null;
  117. // first, find the Criteria inner class
  118. for (InnerClass innerClass : topLevelClass.getInnerClasses()) {
  119. if ("GeneratedCriteria".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$
  120. criteria = innerClass;
  121. break;
  122. }
  123. }
  124. if (criteria == null) {
  125. throw new RuntimeException("GeneratedCriteria not exist");
  126. }
  127. Method method = new Method();
  128. method.setVisibility(JavaVisibility.PROTECTED);
  129. method.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "condition"));
  130. method.addParameter(new Parameter(FullyQualifiedJavaType.getObjectInstance(), "value"));
  131. method.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "property"));
  132. method.setName("addCriterionPattern");
  133. method.addBodyLine("if (value == null) {");
  134. method.addBodyLine("throw new RuntimeException(\"Value for \" + property + \" cannot be null\");");
  135. method.addBodyLine("}");
  136. method.addBodyLine("Criterion c = new Criterion(condition, value);");
  137. method.addBodyLine("c.setPattern(true);");
  138. method.addBodyLine("criteria.add(c);");
  139. criteria.addMethod(method);
  140. }
  141. public void addCriterionPatternField(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
  142. InnerClass criterion = null;
  143. // first, find the Criteria inner class
  144. for (InnerClass innerClass : topLevelClass.getInnerClasses()) {
  145. if ("Criterion".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$
  146. criterion = innerClass;
  147. break;
  148. }
  149. }
  150. if (criterion == null) {
  151. throw new RuntimeException("Criterion not exist");
  152. }
  153. FullyQualifiedJavaType booleanPrimitive = FullyQualifiedJavaType.getBooleanPrimitiveInstance();
  154. Field pattern = new Field();
  155. pattern.setName("pattern");
  156. pattern.setVisibility(JavaVisibility.PRIVATE);
  157. pattern.setType(booleanPrimitive);
  158. criterion.addField(pattern);
  159. Method setPattern = new Method();
  160. setPattern.setVisibility(JavaVisibility.PUBLIC);
  161. setPattern.setName("setPattern");
  162. setPattern.addParameter(new Parameter(booleanPrimitive, "pattern"));
  163. setPattern.addBodyLine("this.pattern = pattern;");
  164. criterion.addMethod(setPattern);
  165. Method isPattern = new Method();
  166. isPattern.setVisibility(JavaVisibility.PUBLIC);
  167. isPattern.setReturnType(booleanPrimitive);
  168. isPattern.setName("isPattern");
  169. isPattern.addBodyLine("return pattern;");
  170. criterion.addMethod(isPattern);
  171. }
  172. public void addFindInSet(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
  173. addFindInSetPattern(topLevelClass, introspectedTable, "findInSet", "find_in_set(" + valueName + ", " + columnName + ")");
  174. }
  175. public void addFindInSetPattern(TopLevelClass topLevelClass, IntrospectedTable introspectedTable, String opName, String pattern) {
  176. InnerClass criteria = null;
  177. // first, find the Criteria inner class
  178. for (InnerClass innerClass : topLevelClass.getInnerClasses()) {
  179. if ("GeneratedCriteria".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$
  180. criteria = innerClass;
  181. break;
  182. }
  183. }
  184. if (criteria == null) {
  185. throw new RuntimeException("GeneratedCriteria not exist");
  186. }
  187. for (IntrospectedColumn introspectedColumn : introspectedTable
  188. .getNonBLOBColumns()) {
  189. if (!introspectedColumn.isJdbcCharacterColumn()
  190. || !introspectedColumn.isStringColumn()) {
  191. continue;
  192. }
  193. Method method = new Method();
  194. method.setVisibility(JavaVisibility.PUBLIC);
  195. method.addParameter(new Parameter(introspectedColumn
  196. .getFullyQualifiedJavaType(), "value")); //$NON-NLS-1$
  197. StringBuilder opNameBuilder = new StringBuilder(opName);
  198. opNameBuilder.setCharAt(0, Character.toUpperCase(opNameBuilder.charAt(0)));
  199. opName = opNameBuilder.toString();
  200. StringBuilder sb = new StringBuilder();
  201. sb.append(introspectedColumn.getJavaProperty());
  202. sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
  203. sb.insert(0, "and"); //$NON-NLS-1$
  204. sb.append(opName);
  205. method.setName(sb.toString());
  206. method.setReturnType(FullyQualifiedJavaType.getCriteriaInstance());
  207. sb.setLength(0);
  208. sb.append("addCriterionPattern(\"")
  209. .append(pattern.replaceAll(columnName, Ibatis2FormattingUtilities.getAliasedActualColumnName(introspectedColumn)))
  210. .append("\", value, \"")
  211. .append(introspectedColumn.getJavaProperty());
  212. sb.append("\");");
  213. method.addBodyLine(sb.toString());
  214. method.addBodyLine("return (Criteria) this;");
  215. criteria.addMethod(method);
  216. }
  217. }
  218. public void addPattern(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
  219. addPatternMethod(topLevelClass, introspectedTable, "pattern");
  220. }
  221. public void addPatternMethod(TopLevelClass topLevelClass, IntrospectedTable introspectedTable, String opName){
  222. InnerClass criteria = null;
  223. // first, find the Criteria inner class
  224. for (InnerClass innerClass : topLevelClass.getInnerClasses()) {
  225. if ("GeneratedCriteria".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$
  226. criteria = innerClass;
  227. break;
  228. }
  229. }
  230. if (criteria == null) {
  231. throw new RuntimeException("GeneratedCriteria not exist");
  232. }
  233. for (IntrospectedColumn introspectedColumn : introspectedTable
  234. .getNonBLOBColumns()) {
  235. if (!introspectedColumn.isJdbcCharacterColumn()
  236. || !introspectedColumn.isStringColumn()) {
  237. continue;
  238. }
  239. Method method = new Method();
  240. method.setVisibility(JavaVisibility.PUBLIC);
  241. method.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "pattern"));
  242. method.addParameter(new Parameter(introspectedColumn
  243. .getFullyQualifiedJavaType(), "value"));
  244. StringBuilder opNameBuilder = new StringBuilder(opName);
  245. opNameBuilder.setCharAt(0, Character.toUpperCase(opNameBuilder.charAt(0)));
  246. opName = opNameBuilder.toString();
  247. StringBuilder sb = new StringBuilder();
  248. sb.append(introspectedColumn.getJavaProperty());
  249. sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
  250. sb.insert(0, "and"); //$NON-NLS-1$
  251. sb.append(opName);
  252. method.setName(sb.toString());
  253. method.setReturnType(FullyQualifiedJavaType.getCriteriaInstance());
  254. sb.setLength(0);
  255. sb.append("addCriterionPattern(pattern.replaceAll(\"")
  256. .append(columnName).append("\", \"")
  257. .append(Ibatis2FormattingUtilities.getAliasedActualColumnName(introspectedColumn)).append("\")")
  258. .append(", value, \"")
  259. .append(introspectedColumn.getJavaProperty());
  260. sb.append("\");");
  261. method.addBodyLine(sb.toString());
  262. method.addBodyLine("return (Criteria) this;");
  263. criteria.addMethod(method);
  264. }
  265. }
  266. }

三、配置插件

  1. <plugin type="com.mk.mybatisgenerator.plugins.MySQLMethodPlugin"/>

发表评论

表情:
评论列表 (有 0 条评论,317人围观)

还没有评论,来说两句吧...

相关阅读