Mybatis生成器插件扩展,生成findInSet方法
Mybatis生成器插件扩展,生成findInSet方法
public Criteria andNameFindInSet(String value) {
addCriterionPattern("find_in_set($value, `name`)", value, "name");
return (Criteria) this;
}
public Criteria andNamePattern(String pattern, String value) {
addCriterionPattern(pattern.replace("##column##", "`name`"), value, "name");
return (Criteria) this;
}
一、生成模式原理
(1)Example.Criterion添加pattern字段
public static class Criterion {
private String condition;
private Object value;
private Object secondValue;
private boolean noValue;
private boolean singleValue;
private boolean betweenValue;
private boolean listValue;
private String typeHandler;
private boolean pattern;
}
(2)Example.GeneratedCriteria加方法addCriterionPattern
protected abstract static class GeneratedCriteria
protected void addCriterionPattern(String condition, Object value, String property) {
if (value == null) {
throw new RuntimeException("Value for " + property + " cannot be null");
}
Criterion c = new Criterion(condition, value);
c.setPattern(true);
criteria.add(c);
}
}
(3) 加对应列FindInSet方法
protected abstract static class GeneratedCriteria {
public Criteria andXXXFindInSet(String value) {
addCriterionPattern("find_in_set(##value##, `xxx`)", value, "xxx");
return (Criteria) this;
}
}
(4)改造XXXSqlProvider.applyWhere的 if (criterion.isNoValue()) 前增加模式代码
if (criterion.isPattern()) {
String value;
if (criterion.getTypeHandler() == null) {
value = String.format(parmPhrase1, "", i, j).trim();
} else {
value = String.format(parmPhrase1_th, "", i, j, criterion.getTypeHandler()).trim();
}
sb.append(criterion.getCondition().replaceAll("##value##", value));
} else if (criterion.isNoValue()) {
sb.append(criterion.getCondition());
} else if (criterion.isSingleValue()) {
}
(5)改造XXXMapper.xml的
<when test="criterion.pattern">
and
<foreach collection="criterion.condition.split('##value##')" item="criterionCond" separator="#{criterion.value}">
${criterionCond}
</foreach>
</when>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
二、插件代码
package com.mk.mybatisgenerator.plugins;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Element;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.codegen.ibatis2.Ibatis2FormattingUtilities;
import java.util.ArrayList;
import java.util.List;
public class MySQLMethodPlugin extends PluginAdapter {
private final String valueName = "##value##";//值占位符
private final String columnName = "##column##";//列名占位符
public MySQLMethodPlugin() {
super();
}
@Override
public boolean validate(List<String> warnings) {
return true;
}
/**
* 重写example
* @param topLevelClass
* @param introspectedTable
* @return
*/
@Override
public boolean modelExampleClassGenerated(TopLevelClass topLevelClass,
IntrospectedTable introspectedTable) {
addCriterionPattern(topLevelClass, introspectedTable);//增加模式匹配
addFindInSet(topLevelClass, introspectedTable);//增加find_in_set方法
addPattern(topLevelClass, introspectedTable);//增加模式方法
return true;
}
/**
* xml ExampleWhere重写
* @param element
* @param introspectedTable
* @return
*/
@Override
public boolean sqlMapExampleWhereClauseElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
XmlElement whereElement = (XmlElement) element.getElements().get(0);
XmlElement foreachElement = (XmlElement) whereElement.getElements().get(0);
XmlElement ifElement = (XmlElement) foreachElement.getElements().get(0);
XmlElement trimElement = (XmlElement) ifElement.getElements().get(0);
XmlElement foreachCriteriaElement = (XmlElement) trimElement.getElements().get(0);
XmlElement chooseElement = (XmlElement) foreachCriteriaElement.getElements().get(0);
for (Element ele : chooseElement.getElements()) {
XmlElement noValueElement = (XmlElement) ele;
for (Attribute attribute : noValueElement.getAttributes()) {
//找到criterion.noValue行插入模式代码
if (attribute.getName().equals("test") && attribute.getValue().equals("criterion.noValue")) {
XmlElement patternElement = new XmlElement("when");
patternElement.addAttribute(new Attribute("test", "criterion.pattern"));
//<foreach collection="oredCriteria" item="criteria" separator="or">
XmlElement forElement = new XmlElement("foreach");
forElement.addAttribute(new Attribute("collection", "criterion.condition.split('" + valueName + "')"));
forElement.addAttribute(new Attribute("item", "criterionCond"));
forElement.addAttribute(new Attribute("separator", "#{criterion.value}"));
forElement.addElement(new TextElement("${criterionCond}"));
patternElement.addElement(new TextElement("and"));
patternElement.addElement(forElement);
chooseElement.addElement(0, patternElement);
return true;
}
}
}
throw new RuntimeException("ChooseElement not exist");
}
/**
* 重写ApplyWhere方法
* @param method
* @param topLevelClass
* @param introspectedTable
* @return
*/
@Override
public boolean providerApplyWhereMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
List<String> lines = method.getBodyLines();
for (int i = 0, len = lines.size(); i < len; i++) {
String line = lines.get(i).trim();
//找到criterion.noValue行插入模式代码
if (line.matches("if\\s*\\(criterion\\.isNoValue\\(\\)\\)\\s*\\{")) {
lines.remove(i);
List<String> appends = new ArrayList<>();
appends.add("if (criterion.isPattern()) {");
appends.add("String value;");
appends.add(" if (criterion.getTypeHandler() == null) {");
appends.add("value = String.format(parmPhrase1, \"\", i, j).trim();");
appends.add("} else {");
appends.add("value = String.format(parmPhrase1_th, \"\", i, j, criterion.getTypeHandler()).trim();");
appends.add("}");
appends.add("sb.append(criterion.getCondition().replaceAll(\"" + valueName + "\", value));");
appends.add("} else " + line);
method.addBodyLines(i, appends);
return true;
}
}
throw new RuntimeException("criterion.isNoValue() not exist");
}
/*
protected void addCriterionPattern(String condition, Object value, String property) {
if (value == null) {
throw new RuntimeException("Value for " + property + " cannot be null");
}
Criterion c = new Criterion(condition, value);
c.setPattern(true);
criteria.add(c);
}
*/
public void addCriterionPattern(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
addCriterionPatternField(topLevelClass, introspectedTable);
InnerClass criteria = null;
// first, find the Criteria inner class
for (InnerClass innerClass : topLevelClass.getInnerClasses()) {
if ("GeneratedCriteria".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$
criteria = innerClass;
break;
}
}
if (criteria == null) {
throw new RuntimeException("GeneratedCriteria not exist");
}
Method method = new Method();
method.setVisibility(JavaVisibility.PROTECTED);
method.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "condition"));
method.addParameter(new Parameter(FullyQualifiedJavaType.getObjectInstance(), "value"));
method.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "property"));
method.setName("addCriterionPattern");
method.addBodyLine("if (value == null) {");
method.addBodyLine("throw new RuntimeException(\"Value for \" + property + \" cannot be null\");");
method.addBodyLine("}");
method.addBodyLine("Criterion c = new Criterion(condition, value);");
method.addBodyLine("c.setPattern(true);");
method.addBodyLine("criteria.add(c);");
criteria.addMethod(method);
}
public void addCriterionPatternField(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
InnerClass criterion = null;
// first, find the Criteria inner class
for (InnerClass innerClass : topLevelClass.getInnerClasses()) {
if ("Criterion".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$
criterion = innerClass;
break;
}
}
if (criterion == null) {
throw new RuntimeException("Criterion not exist");
}
FullyQualifiedJavaType booleanPrimitive = FullyQualifiedJavaType.getBooleanPrimitiveInstance();
Field pattern = new Field();
pattern.setName("pattern");
pattern.setVisibility(JavaVisibility.PRIVATE);
pattern.setType(booleanPrimitive);
criterion.addField(pattern);
Method setPattern = new Method();
setPattern.setVisibility(JavaVisibility.PUBLIC);
setPattern.setName("setPattern");
setPattern.addParameter(new Parameter(booleanPrimitive, "pattern"));
setPattern.addBodyLine("this.pattern = pattern;");
criterion.addMethod(setPattern);
Method isPattern = new Method();
isPattern.setVisibility(JavaVisibility.PUBLIC);
isPattern.setReturnType(booleanPrimitive);
isPattern.setName("isPattern");
isPattern.addBodyLine("return pattern;");
criterion.addMethod(isPattern);
}
public void addFindInSet(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
addFindInSetPattern(topLevelClass, introspectedTable, "findInSet", "find_in_set(" + valueName + ", " + columnName + ")");
}
public void addFindInSetPattern(TopLevelClass topLevelClass, IntrospectedTable introspectedTable, String opName, String pattern) {
InnerClass criteria = null;
// first, find the Criteria inner class
for (InnerClass innerClass : topLevelClass.getInnerClasses()) {
if ("GeneratedCriteria".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$
criteria = innerClass;
break;
}
}
if (criteria == null) {
throw new RuntimeException("GeneratedCriteria not exist");
}
for (IntrospectedColumn introspectedColumn : introspectedTable
.getNonBLOBColumns()) {
if (!introspectedColumn.isJdbcCharacterColumn()
|| !introspectedColumn.isStringColumn()) {
continue;
}
Method method = new Method();
method.setVisibility(JavaVisibility.PUBLIC);
method.addParameter(new Parameter(introspectedColumn
.getFullyQualifiedJavaType(), "value")); //$NON-NLS-1$
StringBuilder opNameBuilder = new StringBuilder(opName);
opNameBuilder.setCharAt(0, Character.toUpperCase(opNameBuilder.charAt(0)));
opName = opNameBuilder.toString();
StringBuilder sb = new StringBuilder();
sb.append(introspectedColumn.getJavaProperty());
sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
sb.insert(0, "and"); //$NON-NLS-1$
sb.append(opName);
method.setName(sb.toString());
method.setReturnType(FullyQualifiedJavaType.getCriteriaInstance());
sb.setLength(0);
sb.append("addCriterionPattern(\"")
.append(pattern.replaceAll(columnName, Ibatis2FormattingUtilities.getAliasedActualColumnName(introspectedColumn)))
.append("\", value, \"")
.append(introspectedColumn.getJavaProperty());
sb.append("\");");
method.addBodyLine(sb.toString());
method.addBodyLine("return (Criteria) this;");
criteria.addMethod(method);
}
}
public void addPattern(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
addPatternMethod(topLevelClass, introspectedTable, "pattern");
}
public void addPatternMethod(TopLevelClass topLevelClass, IntrospectedTable introspectedTable, String opName){
InnerClass criteria = null;
// first, find the Criteria inner class
for (InnerClass innerClass : topLevelClass.getInnerClasses()) {
if ("GeneratedCriteria".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$
criteria = innerClass;
break;
}
}
if (criteria == null) {
throw new RuntimeException("GeneratedCriteria not exist");
}
for (IntrospectedColumn introspectedColumn : introspectedTable
.getNonBLOBColumns()) {
if (!introspectedColumn.isJdbcCharacterColumn()
|| !introspectedColumn.isStringColumn()) {
continue;
}
Method method = new Method();
method.setVisibility(JavaVisibility.PUBLIC);
method.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "pattern"));
method.addParameter(new Parameter(introspectedColumn
.getFullyQualifiedJavaType(), "value"));
StringBuilder opNameBuilder = new StringBuilder(opName);
opNameBuilder.setCharAt(0, Character.toUpperCase(opNameBuilder.charAt(0)));
opName = opNameBuilder.toString();
StringBuilder sb = new StringBuilder();
sb.append(introspectedColumn.getJavaProperty());
sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
sb.insert(0, "and"); //$NON-NLS-1$
sb.append(opName);
method.setName(sb.toString());
method.setReturnType(FullyQualifiedJavaType.getCriteriaInstance());
sb.setLength(0);
sb.append("addCriterionPattern(pattern.replaceAll(\"")
.append(columnName).append("\", \"")
.append(Ibatis2FormattingUtilities.getAliasedActualColumnName(introspectedColumn)).append("\")")
.append(", value, \"")
.append(introspectedColumn.getJavaProperty());
sb.append("\");");
method.addBodyLine(sb.toString());
method.addBodyLine("return (Criteria) this;");
criteria.addMethod(method);
}
}
}
三、配置插件
<plugin type="com.mk.mybatisgenerator.plugins.MySQLMethodPlugin"/>
还没有评论,来说两句吧...