其他分享
首页 > 其他分享> > Mybatis生成器插件扩展,生成OR操作

Mybatis生成器插件扩展,生成OR操作

作者:互联网

Mybatis生成器插件扩展,生成OR操作

        ManExample example = new ManExample();
        ManExample.Criteria and = example.createCriteria();
        and.andNameIsEmpty().andNameFindInSet("a").andNameFindInSetIn(Arrays.asList("1", "2", "3"));

        ManExample.OrCriteria andOr = and.openOrCriteria();
        andOr.andIdEqualTo(1).andNameFindInSetIn(Arrays.asList("5", "6", "7"));

        ManExample.AndCriteria andOrAnd = andOr.openAndCriteria();
        andOrAnd.andIdEqualTo(2).andIdGreaterThan(3);

 

一、生成OR原理

(1)添加OrCriterion和AndCriterion,用来包装Criteria

public abstract static class OpCriterion<E extends AbstractCriteria>  extends Criterion {
	protected E criteria;

	public OpCriterion() {
		super(null);
	}

	public void setCriteria(E criteria) {
		this.criteria = criteria;
	}

	public E getCriteria() {
		return criteria;
	}
}

public static class OrCriterion extends OpCriterion<OrCriteria> {

}

public static class AndCriterion extends OpCriterion<AndCriteria> {

}

(2)GeneratedCriteria类改为泛型

public abstract static class GeneratedCriteria<Criteria> {

}

(3)添加OrCriteria和AndCriteria,用来记录操作链

public abstract static class AbstractCriteria<E>  extends GeneratedCriteria<E> {
	protected GeneratedCriteria root;

	protected Criterion first;

	public GeneratedCriteria getRoot() {
		return this.root;
	}

	public Criterion getFirst() {
		return this.first;
	}

	public AbstractCriteria(GeneratedCriteria root, Criterion criterion) {
		this.root = root;
		this.first = criterion;
	}

	protected void addRoot(int currentIndex) {
		Criterion criterion = this.first;
		if (currentIndex > 0) {
			criterion = criteria.get(currentIndex - 1);
		}
		int index = root.criteria.indexOf(criterion);
		root.criteria.add(index + 1, criteria.get(currentIndex));
		
		if(root instanceof AbstractCriteria){
			((AbstractCriteria)root).addRoot(index + 1);
		}
	}

	@Override
	protected void addCriterion(String condition) {
		super.addCriterion(condition);
		addRoot(criteria.size() - 1);
	}

	@Override
	protected void addCriterion(String condition, Object value, String property) {
		super.addCriterion(condition, value, property);
		addRoot(criteria.size() - 1);
	}

	@Override
	protected void addCriterion(String condition, Object value1, Object value2, String property) {
		super.addCriterion(condition, value1, value2, property);
		addRoot(criteria.size() - 1);
	}

	@Override
	public boolean isValid() {
		for (Criterion criterion : criteria) {
			if(!(criterion instanceof OpCriterion)){
				return true;
			}
		}
		return false;
	}
}

public static class OrCriteria extends AbstractCriteria<OrCriteria> {

	public OrCriteria(GeneratedCriteria root, Criterion criterion) {
		super(root, criterion);
	}

	public AndCriteria openAndCriteria() {
		AndCriterion andCriterion = new AndCriterion();
		this.criteria.add(andCriterion);
		this.addRoot(this.criteria.size() - 1);
		AndCriteria andCriteria = new AndCriteria(this, andCriterion);
		andCriterion.setCriteria(andCriteria);
		return andCriteria;
	}
}

public static class AndCriteria extends AbstractCriteria<AndCriteria> {

	public AndCriteria(GeneratedCriteria root, Criterion criterion) {
		super(root, criterion);
	}

	public OrCriteria openOrCriteria() {
		OrCriterion orCriterion = new OrCriterion();
		this.criteria.add(orCriterion);
		this.addRoot(this.criteria.size() - 1);
		OrCriteria orCriteria = new OrCriteria(this, orCriterion);
		orCriterion.setCriteria(orCriteria);
		return orCriteria;
	}
}

(4)Criteria加泛型和生成入口or方法

public static class Criteria extends GeneratedCriteria<Criteria> {

	public OrCriteria openOrCriteria() {
		OrCriterion orCriterion = new OrCriterion();
		this.criteria.add(orCriterion);
		OrCriteria orCriteria = new OrCriteria(this, orCriterion);
		orCriterion.setCriteria(orCriteria);
		return orCriteria;
	}
}

(5)改Example.applyWhere方法

                java.util.Stack<Criterion> stack = new java.util.Stack();
                for (int j = 0; j <= criterions.size(); j++) {
                    if (j == criterions.size()) {
                        for (Criterion c : stack) {
                            sb.append(")");
                        }
                        stack.clear();
                        continue;
                    }
                    Criterion criterion = criterions.get(j);
                    if (criterion instanceof ManExample.OpCriterion) {
                        ManExample.OpCriterion opCriterion = (ManExample.OpCriterion) criterion;
                        if (opCriterion.getCriteria().isValid()) {
                            if(!stack.isEmpty()){
                                Criterion sCriterion = stack.peek();
                                ManExample.OpCriterion sOpCriterion = (ManExample.OpCriterion) sCriterion;
                                ManExample.AbstractCriteria abstractCriteria = sOpCriterion.getCriteria();
                                List<Criterion> criterionList = abstractCriteria.getAllCriteria();
                                int index = criterionList.indexOf(criterion);
                                if (index < 0) {
                                    stack.pop();
                                    sb.append(")");
                                    j--;
                                    continue;
                                }
                            }
                            stack.add(criterion);
                            ManExample.GeneratedCriteria root = opCriterion.getCriteria().getRoot();
                            Criterion first = opCriterion.getCriteria().getFirst();
                            List<Criterion> rootCriterion = root.getAllCriteria();
                            int firstIndex = rootCriterion.indexOf(first);
                            if (firstIndex > 0) {
                                for (int z = firstIndex - 1; z >= 0; z--) {
                                    Criterion prev = rootCriterion.get(z);
                                    if (prev instanceof ManExample.OpCriterion) {
                                        if (((ManExample.OpCriterion) prev).getCriteria().isValid()) {
                                            break;
                                        }
                                    } else {
                                        if(root instanceof ManExample.OrCriteria) {
                                            sb.append(" or ");
                                        }else {
                                            sb.append(" and ");
                                        }
                                        break;
                                    }
                                }
                            }
                            sb.append("(");
                        }
                        continue;
                    }
                    
                    if (j == 0) {
                        //do nothing
                    } else if (stack.isEmpty()) {
                        sb.append(" and ");
                    } else if (stack.peek() instanceof ManExample.OpCriterion) {
                        ManExample.OpCriterion opCriterion = (ManExample.OpCriterion) stack.peek();
                        ManExample.AbstractCriteria abstractCriteria = opCriterion.getCriteria();
                        List<Criterion> criterionList = abstractCriteria.getAllCriteria();
                        int index = criterionList.indexOf(criterion);
                        if (index == 0) {
                            //do nothing
                        } else if (index > 0) {
                            if (opCriterion instanceof ManExample.AndCriterion) {
                                sb.append(" and ");
                            } else {
                                sb.append(" or ");
                            }
                        } else {
                            stack.pop();
                            sb.append(")");
                            j--;
                            continue;
                        }
                    }

(6) xml更改,加XmlCriteria类和转换方法,更改xml逻辑

public static class Criteria extends GeneratedCriteria<Criteria> {

	public List<XmlCriterion> getXmlCriterion() {
		List<XmlCriterion> list = new java.util.LinkedList<>();
		List<Criterion> criterions = criteria;
		java.util.Stack<Criterion> stack = new java.util.Stack();
		for (int j = 0; j <= criterions.size(); j++) {
			if (j == criterions.size()) {
				for (Criterion c : stack) {
					list.add(new XmlCriterion(c, false, false, false, true));
				}
				stack.clear();
				continue;
			}
			
			Criterion criterion = criterions.get(j);
			if (criterion instanceof ManExample.OpCriterion) {
				ManExample.OpCriterion opCriterion = (ManExample.OpCriterion) criterion;
				if (opCriterion.getCriteria().isValid()) {
					
					if (!stack.isEmpty()) {
						Criterion sCriterion = stack.peek();
						ManExample.OpCriterion sOpCriterion = (ManExample.OpCriterion) sCriterion;
						ManExample.AbstractCriteria abstractCriteria = sOpCriterion.getCriteria();
						List<Criterion> criterionList = abstractCriteria.getAllCriteria();
						int index = criterionList.indexOf(criterion);
						if (index < 0) {
							stack.pop();
							list.add(new XmlCriterion(criterion, false, false, false, true));
							j--;
							continue;
						}
					}
					
					stack.add(criterion);
					boolean isFirst = true;
					boolean isAnd = false;
					ManExample.GeneratedCriteria root = opCriterion.getCriteria().getRoot();
					Criterion first = opCriterion.getCriteria().getFirst();
					List<Criterion> rootCriterion = root.getAllCriteria();
					int firstIndex = rootCriterion.indexOf(first);
					if (firstIndex > 0) {
						for (int z = firstIndex - 1; z >= 0; z--) {
							Criterion prev = rootCriterion.get(z);
							if (prev instanceof ManExample.OpCriterion) {
								if (((ManExample.OpCriterion) prev).getCriteria().isValid()) {
									break;
								}
							} else {
								isFirst = false;
								if (root instanceof ManExample.OrCriteria) {
									isAnd = false;
								} else {
									isAnd = true;
								}
								break;
							}
						}
					}
					list.add(new XmlCriterion(criterion, !isAnd, isFirst, true, false));
				}
				continue;
			}
			
			boolean isFirst = false;
			boolean isAnd = false;
			if (j == 0) {
				isFirst = true;
			} else if (stack.isEmpty()) {
				isAnd = true;
			} else if (stack.peek() instanceof ManExample.OpCriterion) {
				ManExample.OpCriterion opCriterion = (ManExample.OpCriterion) stack.peek();
				ManExample.AbstractCriteria abstractCriteria = opCriterion.getCriteria();
				List<Criterion> criterionList = abstractCriteria.getAllCriteria();
				int index = criterionList.indexOf(criterion);
				if (index == 0) {
					isFirst = true;
				} else if (index > 0) {
					if (opCriterion instanceof ManExample.AndCriterion) {
						isAnd = true;
					} else {
						isAnd = false;
					}
				} else {
					stack.pop();
					list.add(new XmlCriterion(criterion,false, false, false, true));
					j--;
					continue;
				}
			}
			list.add(new XmlCriterion(criterion, !isAnd, isFirst, false, false));
		}
		
		return list;
	}
}
public static class XmlCriterion {
	protected Criterion criterion;

	protected boolean or;

	protected boolean first;

	protected boolean start;

	protected boolean end;

	public XmlCriterion(Criterion criterion, boolean or, boolean first, boolean start, boolean end) {
		this.criterion = criterion;
		this.or = or;
		this.first = first;
		this.start = start;
		this.end = end;
	}

	public Criterion getCriterion() {
		return this.criterion;
	}

	public List<Criterion> getCriterions() {
		List<Criterion> list = new ArrayList<>();
		if (this.criterion != null) {
			list.add(this.criterion);
		}
		return list;
	}

	public boolean isOr() {
		return this.or;
	}

	public boolean isAnd() {
		return !this.isOr();
	}

	public boolean isFirst() {
		return this.first;
	}

	public boolean isStart() {
		return this.start;
	}

	public boolean isEnd() {
		return this.end;
	}
}
            <foreach collection="criteria.xmlCriterion" item="xmlCriterion">
              <choose>
                <when test="xmlCriterion.isStart()">
                  <if test="!xmlCriterion.isFirst()">
                    <if test="xmlCriterion.isOr()">
                       or 
                    </if>
                    <if test="xmlCriterion.isAnd()">
                       and 
                    </if>
                  </if>
                  (
                </when>
                <when test="xmlCriterion.isEnd()">
                  )
                </when>
                <otherwise>
                  <if test="xmlCriterion.isOr()">
                    <if test="!xmlCriterion.isFirst()">
                       or 
                    </if>
                     1=1 
                  </if>
                  <if test="xmlCriterion.isAnd() and xmlCriterion.isFirst()">
                     1=1 
                  </if>
                  <foreach collection="xmlCriterion.criterions" item="criterion">
                    <choose>

 

二、插件代码

package com.mk.mybatisgenerator.plugins;

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 java.util.*;

public class OrPlugin extends PluginAdapter {


    public OrPlugin() {
        super();
    }

    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }

    //            <foreach collection="criteria.xmlCriterion" item="xmlCriterion">
    //              <choose>
    //                <when test="xmlCriterion.isStart()">
    //                  <if test="!xmlCriterion.isFirst()">
    //                    <if test="xmlCriterion.isOr()">
    //                       or
    //                    </if>
    //                    <if test="xmlCriterion.isAnd()">
    //                       and
    //                    </if>
    //                  </if>
    //                  (
    //                </when>
    //                <when test="xmlCriterion.isEnd()">
    //                  )
    //                </when>
    //                <otherwise>
    //                  <if test="xmlCriterion.isOr()">
    //                    <if test="!xmlCriterion.isFirst()">
    //                       or
    //                    </if>
    //                     1=1
    //                  </if>
    //                  <if test="xmlCriterion.isAnd() and xmlCriterion.isFirst()">
    //                     1=1
    //                  </if>
    //                  <foreach collection="xmlCriterion.criterions" item="criterion">
    //                    <choose>
    //xml where条件生成
    @Override
    public boolean sqlMapExampleWhereClauseElementGenerated(XmlElement xmlElement, IntrospectedTable introspectedTable) {

        List<Element> elementList = new LinkedList<>();
        elementList.add(xmlElement);
        while (!elementList.isEmpty()) {
            Element parent = elementList.remove(0);
            if (!(parent instanceof XmlElement)) {
                continue;
            }
            XmlElement xmlParent = (XmlElement) parent;
            List<Element> elements = xmlParent.getElements();
            elementList.addAll(0, elements);
            for (int i = 0, len = elements.size(); i < len; i++) {
                Element ele = elements.get(i);
                if (!(ele instanceof XmlElement)) {
                    continue;
                }
                XmlElement element = (XmlElement) ele;
                if (!element.getName().equals("foreach") || element.getAttributes().size() != 2) {
                    continue;
                }

                Map<String, Attribute> attributeMap = new HashMap<>();
                for (Attribute attribute : element.getAttributes()) {
                    attributeMap.put(attribute.getName(), attribute);
                }
                //找到<foreach collection="criteria.criteria" item="criterion">代码
                if (attributeMap.containsKey("collection") && Objects.equals(attributeMap.get("collection").getValue(), "criteria.criteria")
                        && attributeMap.containsKey("item") && Objects.equals(attributeMap.get("item").getValue(), "criterion")) {

                    //开始括号
                    XmlElement startWhenElement = new XmlElement("when");
                    {
                        XmlElement ifElement = new XmlElement("if");
                        ifElement.addAttribute(new Attribute("test", "!xmlCriterion.isFirst()"));

                        XmlElement ifOrElement = new XmlElement("if");
                        ifOrElement.addAttribute(new Attribute("test", "xmlCriterion.isOr()"));
                        ifOrElement.addElement(new TextElement(" or "));

                        XmlElement ifAndElement = new XmlElement("if");
                        ifAndElement.addAttribute(new Attribute("test", "xmlCriterion.isAnd()"));
                        ifAndElement.addElement(new TextElement(" and "));

                        ifElement.addElement(ifOrElement);
                        ifElement.addElement(ifAndElement);

                        startWhenElement.addAttribute(new Attribute("test", "xmlCriterion.isStart()"));
                        startWhenElement.addElement(ifElement);
                        startWhenElement.addElement(new TextElement("("));

                    }

                    //结束括号
                    XmlElement endWhenElement = new XmlElement("when");
                    endWhenElement.addAttribute(new Attribute("test", "xmlCriterion.isEnd()"));
                    endWhenElement.addElement(new TextElement(")"));

                    //otherwise
                    XmlElement otherwiseElement = new XmlElement("otherwise");
                    {

                        XmlElement ifFirstElement = new XmlElement("if");
                        ifFirstElement.addAttribute(new Attribute("test", "!xmlCriterion.isFirst()"));
                        ifFirstElement.addElement(new TextElement(" or "));

                        XmlElement ifOrElement = new XmlElement("if");
                        ifOrElement.addAttribute(new Attribute("test", "xmlCriterion.isOr()"));
                        ifOrElement.addElement(ifFirstElement);
                        ifOrElement.addElement(new TextElement(" 1=1 "));

                        XmlElement ifAndElement = new XmlElement("if");
                        ifAndElement.addAttribute(new Attribute("test", "xmlCriterion.isAnd() and xmlCriterion.isFirst()"));
                        ifAndElement.addElement(new TextElement(" 1=1 "));

                        otherwiseElement.addElement(ifOrElement);
                        otherwiseElement.addElement(ifAndElement);

                        XmlElement foreachElement = new XmlElement("foreach");
                        foreachElement.addAttribute(new Attribute("collection", "xmlCriterion.criterions"));
                        foreachElement.addAttribute(new Attribute("item", "criterion"));
                        for (Element e : element.getElements()) {
                            foreachElement.addElement(e);
                        }
                        otherwiseElement.addElement(foreachElement);

                        element.getElements().clear();
                    }

                    XmlElement orChooseElement = new XmlElement("choose");
                    orChooseElement.addElement(startWhenElement);
                    orChooseElement.addElement(endWhenElement);
                    orChooseElement.addElement(otherwiseElement);

                    element.getAttributes().clear();
                    element.addAttribute(new Attribute("collection", "criteria.xmlCriterion"));
                    element.addAttribute(new Attribute("item", "xmlCriterion"));
                    element.addElement(orChooseElement);
                    return true;
                }

            }
        }

        throw new RuntimeException("<foreach collection=\"criteria.criteria\" item=\"criterion\"> not exist");
    }

    //example类生成
    @Override
    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass,
                                              IntrospectedTable introspectedTable) {


        InnerClass generatedCriteria = generatedCriteria(topLevelClass);
        InnerClass criteria = criteria(topLevelClass);
        InnerClass abstractCriteria = addAbstractCriteria(topLevelClass);
        InnerClass orCriteria = addOrCriteria(topLevelClass, abstractCriteria);
        InnerClass andCriteria = addAndCriteria(topLevelClass, abstractCriteria);
        InnerClass opCriterion = addOpCriterion(topLevelClass);
        InnerClass orCriterion = addOrCriterion(topLevelClass, opCriterion);
        InnerClass andCriterion = addAndCriterion(topLevelClass, opCriterion);

        addCriteriaOrMethod(topLevelClass);

        //适配生成xml解析方法
        String type = introspectedTable.getContext().getJavaClientGeneratorConfiguration().getConfigurationType();
        if("XMLMAPPER".equalsIgnoreCase(type)) {
            InnerClass xmlCriterion = addXmlCriterion(topLevelClass);
            addXmlCriteriaMethod(topLevelClass, xmlCriterion);
        }
        return true;
    }

    //添加xml解析Criteria方法
    private void addXmlCriteriaMethod(TopLevelClass topLevelClass, InnerClass xmlCriterion) {

        InnerClass criteria = null;
        // first, find the Criteria inner class
        for (InnerClass innerClass : topLevelClass.getInnerClasses()) {
            if ("Criteria".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$
                criteria = innerClass;
                break;
            }
        }

        if (criteria == null) {
            throw new RuntimeException("Criteria not exist");
        }

        String topClassName = topLevelClass.getType().getShortName();

        Method getXmlCriterion = new Method();
        getXmlCriterion.setVisibility(JavaVisibility.PUBLIC);
        getXmlCriterion.setName("getXmlCriterion");
        getXmlCriterion.setReturnType(new FullyQualifiedJavaType("List<XmlCriterion>"));
        getXmlCriterion.addBodyLine("List<XmlCriterion> list = new java.util.LinkedList<>();");
        getXmlCriterion.addBodyLine("List<Criterion> criterions = criteria;");
        getXmlCriterion.addBodyLine("java.util.Stack<Criterion> stack = new java.util.Stack();");
        getXmlCriterion.addBodyLine("for (int j = 0; j <= criterions.size(); j++) {");
        getXmlCriterion.addBodyLine("if (j == criterions.size()) {");
        getXmlCriterion.addBodyLine("for (Criterion c : stack) {");
        getXmlCriterion.addBodyLine("list.add(new XmlCriterion(c, false, false, false, true));");
        getXmlCriterion.addBodyLine("}");
        getXmlCriterion.addBodyLine("stack.clear();");
        getXmlCriterion.addBodyLine("continue;");
        getXmlCriterion.addBodyLine("}");
        getXmlCriterion.addBodyLine("");

        getXmlCriterion.addBodyLine("Criterion criterion = criterions.get(j);");
        getXmlCriterion.addBodyLine("if (criterion instanceof " + topClassName + ".OpCriterion) {");
        getXmlCriterion.addBodyLine(topClassName + ".OpCriterion opCriterion = (" + topClassName + ".OpCriterion) criterion;");
        getXmlCriterion.addBodyLine("if (opCriterion.getCriteria().isValid()) {");
        getXmlCriterion.addBodyLine("");

        getXmlCriterion.addBodyLine("if (!stack.isEmpty()) {");
        getXmlCriterion.addBodyLine("Criterion sCriterion = stack.peek();");
        getXmlCriterion.addBodyLine(topClassName + ".OpCriterion sOpCriterion = (" + topClassName + ".OpCriterion) sCriterion;");
        getXmlCriterion.addBodyLine(topClassName + ".AbstractCriteria abstractCriteria = sOpCriterion.getCriteria();");
        getXmlCriterion.addBodyLine("List<Criterion> criterionList = abstractCriteria.getAllCriteria();");
        getXmlCriterion.addBodyLine("int index = criterionList.indexOf(criterion);");
        getXmlCriterion.addBodyLine("if (index < 0) {");
        getXmlCriterion.addBodyLine("stack.pop();");
        getXmlCriterion.addBodyLine("list.add(new XmlCriterion(criterion, false, false, false, true));");
        getXmlCriterion.addBodyLine("j--;");
        getXmlCriterion.addBodyLine("continue;");
        getXmlCriterion.addBodyLine("}");
        getXmlCriterion.addBodyLine("}");
        getXmlCriterion.addBodyLine("");

        getXmlCriterion.addBodyLine("stack.add(criterion);");
        getXmlCriterion.addBodyLine("boolean isFirst = true;");
        getXmlCriterion.addBodyLine("boolean isAnd = false;");
        getXmlCriterion.addBodyLine(topClassName + ".GeneratedCriteria root = opCriterion.getCriteria().getRoot();");
        getXmlCriterion.addBodyLine("Criterion first = opCriterion.getCriteria().getFirst();");
        getXmlCriterion.addBodyLine("List<Criterion> rootCriterion = root.getAllCriteria();");
        getXmlCriterion.addBodyLine("int firstIndex = rootCriterion.indexOf(first);");
        getXmlCriterion.addBodyLine("if (firstIndex > 0) {");
        getXmlCriterion.addBodyLine("for (int z = firstIndex - 1; z >= 0; z--) {");
        getXmlCriterion.addBodyLine("Criterion prev = rootCriterion.get(z);");
        getXmlCriterion.addBodyLine("if (prev instanceof " + topClassName + ".OpCriterion) {");
        getXmlCriterion.addBodyLine("if (((" + topClassName + ".OpCriterion) prev).getCriteria().isValid()) {");
        getXmlCriterion.addBodyLine("break;");
        getXmlCriterion.addBodyLine("}");
        getXmlCriterion.addBodyLine("} else {");
        getXmlCriterion.addBodyLine("isFirst = false;");
        getXmlCriterion.addBodyLine("if (root instanceof " + topClassName + ".OrCriteria) {");
        getXmlCriterion.addBodyLine("isAnd = false;");
        getXmlCriterion.addBodyLine("} else {");
        getXmlCriterion.addBodyLine("isAnd = true;");
        getXmlCriterion.addBodyLine("}");
        getXmlCriterion.addBodyLine("break;");
        getXmlCriterion.addBodyLine("}");
        getXmlCriterion.addBodyLine("}");
        getXmlCriterion.addBodyLine("}");
        getXmlCriterion.addBodyLine("list.add(new XmlCriterion(criterion, !isAnd, isFirst, true, false));");
        getXmlCriterion.addBodyLine("}");
        getXmlCriterion.addBodyLine("continue;");
        getXmlCriterion.addBodyLine("}");
        getXmlCriterion.addBodyLine("");

        getXmlCriterion.addBodyLine("boolean isFirst = false;");
        getXmlCriterion.addBodyLine("boolean isAnd = false;");
        getXmlCriterion.addBodyLine("if (j == 0) {");
        getXmlCriterion.addBodyLine("isFirst = true;");
        getXmlCriterion.addBodyLine("} else if (stack.isEmpty()) {");
        getXmlCriterion.addBodyLine("isAnd = true;");
        getXmlCriterion.addBodyLine("} else if (stack.peek() instanceof " + topClassName + ".OpCriterion) {");
        getXmlCriterion.addBodyLine(topClassName + ".OpCriterion opCriterion = (" + topClassName + ".OpCriterion) stack.peek();");
        getXmlCriterion.addBodyLine(topClassName + ".AbstractCriteria abstractCriteria = opCriterion.getCriteria();");
        getXmlCriterion.addBodyLine("List<Criterion> criterionList = abstractCriteria.getAllCriteria();");
        getXmlCriterion.addBodyLine("int index = criterionList.indexOf(criterion);");
        getXmlCriterion.addBodyLine("if (index == 0) {");
        getXmlCriterion.addBodyLine("isFirst = true;");
        getXmlCriterion.addBodyLine("} else if (index > 0) {");
        getXmlCriterion.addBodyLine("if (opCriterion instanceof " + topClassName + ".AndCriterion) {");
        getXmlCriterion.addBodyLine("isAnd = true;");
        getXmlCriterion.addBodyLine("} else {");
        getXmlCriterion.addBodyLine("isAnd = false;");
        getXmlCriterion.addBodyLine("}");
        getXmlCriterion.addBodyLine("} else {");
        getXmlCriterion.addBodyLine("stack.pop();");
        getXmlCriterion.addBodyLine("list.add(new XmlCriterion(criterion,false, false, false, true));");
        getXmlCriterion.addBodyLine("j--;");
        getXmlCriterion.addBodyLine("continue;");
        getXmlCriterion.addBodyLine("}");
        getXmlCriterion.addBodyLine("}");
        getXmlCriterion.addBodyLine("list.add(new XmlCriterion(criterion, !isAnd, isFirst, false, false));");
        getXmlCriterion.addBodyLine("}");
        getXmlCriterion.addBodyLine("");

        getXmlCriterion.addBodyLine("return list;");
        criteria.addMethod(getXmlCriterion);
    }

    //添加XmlCriterion类
    private InnerClass addXmlCriterion(TopLevelClass topLevelClass) {
        InnerClass innerClass = new InnerClass("XmlCriterion");
        innerClass.setStatic(true);
        innerClass.setVisibility(JavaVisibility.PUBLIC);

        Field criterion = new Field();
        criterion.setVisibility(JavaVisibility.PROTECTED);
        criterion.setType(new FullyQualifiedJavaType("Criterion"));
        criterion.setName("criterion");
        innerClass.addField(criterion);

        Field or = new Field();
        or.setVisibility(JavaVisibility.PROTECTED);
        or.setType(new FullyQualifiedJavaType("boolean"));
        or.setName("or");
        innerClass.addField(or);

        Field first = new Field();
        first.setVisibility(JavaVisibility.PROTECTED);
        first.setType(new FullyQualifiedJavaType("boolean"));
        first.setName("first");
        innerClass.addField(first);

        Field start = new Field();
        start.setVisibility(JavaVisibility.PROTECTED);
        start.setType(new FullyQualifiedJavaType("boolean"));
        start.setName("start");
        innerClass.addField(start);

        Field end = new Field();
        end.setVisibility(JavaVisibility.PROTECTED);
        end.setType(new FullyQualifiedJavaType("boolean"));
        end.setName("end");
        innerClass.addField(end);

        Method constructor = new Method();
        constructor.setVisibility(JavaVisibility.PUBLIC);
        constructor.setConstructor(true);
        constructor.setName("XmlCriterion");
        constructor.addParameter(new Parameter(new FullyQualifiedJavaType("Criterion"), "criterion"));
        constructor.addParameter(new Parameter(new FullyQualifiedJavaType("boolean"), "or"));
        constructor.addParameter(new Parameter(new FullyQualifiedJavaType("boolean"), "first"));
        constructor.addParameter(new Parameter(new FullyQualifiedJavaType("boolean"), "start"));
        constructor.addParameter(new Parameter(new FullyQualifiedJavaType("boolean"), "end"));
        constructor.addBodyLine("this.criterion = criterion;");
        constructor.addBodyLine("this.or = or;");
        constructor.addBodyLine("this.first = first;");
        constructor.addBodyLine("this.start = start;");
        constructor.addBodyLine("this.end = end;");
        innerClass.addMethod(constructor);

        Method getCriterion = new Method();
        getCriterion.setVisibility(JavaVisibility.PUBLIC);
        getCriterion.setName("getCriterion");
        getCriterion.setReturnType(new FullyQualifiedJavaType("Criterion"));
        getCriterion.addBodyLine("return this.criterion;");
        innerClass.addMethod(getCriterion);

        Method getCriterions = new Method();
        getCriterions.setVisibility(JavaVisibility.PUBLIC);
        getCriterions.setName("getCriterions");
        getCriterions.setReturnType(new FullyQualifiedJavaType("List<Criterion>"));
        getCriterions.addBodyLine("List<Criterion> list = new ArrayList<>();");
        getCriterions.addBodyLine("if (this.criterion != null) {");
        getCriterions.addBodyLine("list.add(this.criterion);");
        getCriterions.addBodyLine("}");
        getCriterions.addBodyLine("return list;");
        innerClass.addMethod(getCriterions);


        Method isOr = new Method();
        isOr.setVisibility(JavaVisibility.PUBLIC);
        isOr.setName("isOr");
        isOr.setReturnType(new FullyQualifiedJavaType("boolean"));
        isOr.addBodyLine("return this.or;");
        innerClass.addMethod(isOr);

        Method isAnd = new Method();
        isAnd.setVisibility(JavaVisibility.PUBLIC);
        isAnd.setName("isAnd");
        isAnd.setReturnType(new FullyQualifiedJavaType("boolean"));
        isAnd.addBodyLine("return !this.isOr();");
        innerClass.addMethod(isAnd);

        Method isFirst = new Method();
        isFirst.setVisibility(JavaVisibility.PUBLIC);
        isFirst.setName("isFirst");
        isFirst.setReturnType(new FullyQualifiedJavaType("boolean"));
        isFirst.addBodyLine("return this.first;");
        innerClass.addMethod(isFirst);

        Method isStart = new Method();
        isStart.setVisibility(JavaVisibility.PUBLIC);
        isStart.setName("isStart");
        isStart.setReturnType(new FullyQualifiedJavaType("boolean"));
        isStart.addBodyLine("return this.start;");
        innerClass.addMethod(isStart);

        Method isEnd = new Method();
        isEnd.setVisibility(JavaVisibility.PUBLIC);
        isEnd.setName("isEnd");
        isEnd.setReturnType(new FullyQualifiedJavaType("boolean"));
        isEnd.addBodyLine("return this.end;");
        innerClass.addMethod(isEnd);

        topLevelClass.addInnerClass(innerClass);
        return innerClass;
    }

    //更改GeneratedCriteria为泛型类
    private InnerClass generatedCriteria(TopLevelClass topLevelClass) {

        InnerClass innerClass1 = null;
        // first, find the Criteria inner class
        for (InnerClass innerClass : topLevelClass.getInnerClasses()) {
            if ("GeneratedCriteria".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$
                innerClass1 = innerClass;
                break;
            }
        }
        if (innerClass1 == null) {
            throw new RuntimeException("GeneratedCriteria not exist");
        }

        innerClass1.setVisibility(JavaVisibility.PUBLIC);
        innerClass1.addTypeParameter(new TypeParameter("Criteria"));
        return innerClass1;
    }

    //更改Criteria为继承GeneratedCriteria泛型类
    private InnerClass criteria(TopLevelClass topLevelClass) {

        InnerClass criteria = null;
        // first, find the Criteria inner class
        for (InnerClass innerClass : topLevelClass.getInnerClasses()) {
            if ("Criteria".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$
                criteria = innerClass;
                break;
            }
        }
        if (criteria == null) {
            throw new RuntimeException("GeneratedCriteria not exist");
        }

        criteria.setSuperClass("GeneratedCriteria<Criteria>");
        return criteria;
    }

    //加OpCriterion抽象类
    private InnerClass addOpCriterion(TopLevelClass topLevelClass) {

        InnerClass innerClass = new InnerClass("OpCriterion");
        innerClass.setSuperClass("Criterion");
        innerClass.setStatic(true);
        innerClass.setAbstract(true);
        innerClass.setVisibility(JavaVisibility.PUBLIC);
        innerClass.addTypeParameter(new TypeParameter("E extends AbstractCriteria"));

        Field criteria = new Field();
        criteria.setVisibility(JavaVisibility.PROTECTED);
        criteria.setType(new FullyQualifiedJavaType("E"));
        criteria.setName("criteria");
        innerClass.addField(criteria);


        Method constructor = new Method();
        constructor.setVisibility(JavaVisibility.PUBLIC);
        constructor.setConstructor(true);
        constructor.setName("OpCriterion");
        constructor.addBodyLine("super(null);");
        innerClass.addMethod(constructor);

        Method setOrCriteria = new Method();
        setOrCriteria.setVisibility(JavaVisibility.PUBLIC);
        setOrCriteria.setName("setCriteria");
        setOrCriteria.addParameter(new Parameter(new FullyQualifiedJavaType("E"), "criteria"));
        setOrCriteria.addBodyLine("this.criteria = criteria;");
        innerClass.addMethod(setOrCriteria);

        Method getOrCriteria = new Method();
        getOrCriteria.setVisibility(JavaVisibility.PUBLIC);
        getOrCriteria.setName("getCriteria");
        getOrCriteria.setReturnType(new FullyQualifiedJavaType("E"));
        getOrCriteria.addBodyLine("return criteria;");
        innerClass.addMethod(getOrCriteria);

        topLevelClass.addInnerClass(innerClass);
        return innerClass;
    }

    //加AndCriterion类,包装AndCriteria
    private InnerClass addAndCriterion(TopLevelClass topLevelClass, InnerClass opCriterion) {

        InnerClass innerClass = new InnerClass("AndCriterion");
        innerClass.setSuperClass(opCriterion.getType().getShortName() + "<AndCriteria>");
        innerClass.setStatic(true);
        innerClass.setVisibility(JavaVisibility.PUBLIC);

        topLevelClass.addInnerClass(innerClass);
        return innerClass;
    }

    //加OrCriterion类,包装OrCriteria
    private InnerClass addOrCriterion(TopLevelClass topLevelClass, InnerClass opCriterion) {

        InnerClass innerClass = new InnerClass("OrCriterion");
        innerClass.setSuperClass(opCriterion.getType().getShortName() + "<OrCriteria>");
        innerClass.setStatic(true);
        innerClass.setVisibility(JavaVisibility.PUBLIC);

        topLevelClass.addInnerClass(innerClass);
        return innerClass;
    }

    //加AndCriteria类,继承AbstractCriteria类
    private InnerClass addAndCriteria(TopLevelClass topLevelClass, InnerClass abstractCriteria) {

        FullyQualifiedJavaType criteria = new FullyQualifiedJavaType("GeneratedCriteria");

        InnerClass innerClass = new InnerClass("AndCriteria");
        innerClass.setSuperClass(abstractCriteria.getType().getShortName() + "<AndCriteria>");
        innerClass.setStatic(true);
        innerClass.setVisibility(JavaVisibility.PUBLIC);

        Method constructor = new Method();
        constructor.setVisibility(JavaVisibility.PUBLIC);
        constructor.setConstructor(true);
        constructor.setName("AndCriteria");
        constructor.addParameter(new Parameter(criteria, "root"));
        constructor.addParameter(new Parameter(new FullyQualifiedJavaType("Criterion"), "criterion"));
        constructor.addBodyLine("super(root, criterion);");
        innerClass.addMethod(constructor);

        Method or = new Method();
        or.setVisibility(JavaVisibility.PUBLIC);
        or.setName("openOrCriteria");
        or.setReturnType(new FullyQualifiedJavaType("OrCriteria"));
        or.addBodyLine("OrCriterion orCriterion = new OrCriterion();");
        or.addBodyLine("this.criteria.add(orCriterion);");
        or.addBodyLine("this.addRoot(this.criteria.size() - 1);");
        or.addBodyLine("OrCriteria orCriteria = new OrCriteria(this, orCriterion);");
        or.addBodyLine("orCriterion.setCriteria(orCriteria);");
        or.addBodyLine("return orCriteria;");
        innerClass.addMethod(or);

        topLevelClass.addInnerClass(innerClass);
        return innerClass;
    }

    //加OrCriteria类,继承AbstractCriteria类
    private InnerClass addOrCriteria(TopLevelClass topLevelClass, InnerClass abstractCriteria) {

        FullyQualifiedJavaType criteria = new FullyQualifiedJavaType("GeneratedCriteria");

        InnerClass innerClass = new InnerClass("OrCriteria");
        innerClass.setSuperClass(abstractCriteria.getType() + "<OrCriteria>");
        innerClass.setStatic(true);
        innerClass.setVisibility(JavaVisibility.PUBLIC);

        Method constructor = new Method();
        constructor.setVisibility(JavaVisibility.PUBLIC);
        constructor.setConstructor(true);
        constructor.setName("OrCriteria");
        constructor.addParameter(new Parameter(criteria, "root"));
        constructor.addParameter(new Parameter(new FullyQualifiedJavaType("Criterion"), "criterion"));
        constructor.addBodyLine("super(root, criterion);");
        innerClass.addMethod(constructor);

        Method and = new Method();
        and.setVisibility(JavaVisibility.PUBLIC);
        and.setName("openAndCriteria");
        and.setReturnType(new FullyQualifiedJavaType("AndCriteria"));
        and.addBodyLine("AndCriterion andCriterion = new AndCriterion();");
        and.addBodyLine("this.criteria.add(andCriterion);");
        and.addBodyLine("this.addRoot(this.criteria.size() - 1);");
        and.addBodyLine("AndCriteria andCriteria = new AndCriteria(this, andCriterion);");
        and.addBodyLine("andCriterion.setCriteria(andCriteria);");
        and.addBodyLine("return andCriteria;");
        innerClass.addMethod(and);

        topLevelClass.addInnerClass(innerClass);
        return innerClass;
    }

    //加AbstractCriteria类
    private InnerClass addAbstractCriteria(TopLevelClass topLevelClass) {

        FullyQualifiedJavaType criteria = new FullyQualifiedJavaType("GeneratedCriteria");

        InnerClass innerClass = new InnerClass("AbstractCriteria");
        innerClass.addTypeParameter(new TypeParameter("E"));
        innerClass.setSuperClass("GeneratedCriteria<E>");
        innerClass.setAbstract(true);
        innerClass.setStatic(true);
        innerClass.setVisibility(JavaVisibility.PUBLIC);

        Field root = new Field();
        root.setVisibility(JavaVisibility.PROTECTED);
        root.setType(criteria);
        root.setName("root");
        innerClass.addField(root);


        Method getRoot = new Method();
        getRoot.setVisibility(JavaVisibility.PUBLIC);
        getRoot.setName("getRoot");
        getRoot.setReturnType(criteria);
        getRoot.addBodyLine("return this.root;");
        innerClass.addMethod(getRoot);

        Field first = new Field();
        first.setVisibility(JavaVisibility.PROTECTED);
        first.setType(new FullyQualifiedJavaType("Criterion"));
        first.setName("first");
        innerClass.addField(first);

        Method getFirst = new Method();
        getFirst.setVisibility(JavaVisibility.PUBLIC);
        getFirst.setReturnType(new FullyQualifiedJavaType("Criterion"));
        getFirst.setName("getFirst");
        getFirst.addBodyLine("return this.first;");
        innerClass.addMethod(getFirst);

        Method constructor = new Method();
        constructor.setVisibility(JavaVisibility.PUBLIC);
        constructor.setConstructor(true);
        constructor.setName("AbstractCriteria");
        constructor.addParameter(new Parameter(criteria, "root"));
        constructor.addParameter(new Parameter(new FullyQualifiedJavaType("Criterion"), "criterion"));
        constructor.addBodyLine("this.root = root;");
        constructor.addBodyLine("this.first = criterion;");
        innerClass.addMethod(constructor);


        Method addRoot = new Method();
        addRoot.setVisibility(JavaVisibility.PROTECTED);
        addRoot.setName("addRoot");
        addRoot.addParameter(new Parameter(FullyQualifiedJavaType.getIntInstance(), "currentIndex"));
        addRoot.addBodyLine("Criterion criterion = this.first;");
        addRoot.addBodyLine("if (currentIndex > 0) {");
        addRoot.addBodyLine("criterion = criteria.get(currentIndex - 1);");
        addRoot.addBodyLine("}");
        addRoot.addBodyLine("int index = root.criteria.indexOf(criterion);");
        addRoot.addBodyLine("root.criteria.add(index + 1, criteria.get(currentIndex));");
        addRoot.addBodyLine("");
        addRoot.addBodyLine("if(root instanceof AbstractCriteria){");
        addRoot.addBodyLine("((AbstractCriteria)root).addRoot(index + 1);");
        addRoot.addBodyLine("}");
        innerClass.addMethod(addRoot);

        Method addCriterion1 = new Method();
        addCriterion1.setVisibility(JavaVisibility.PROTECTED);
        addCriterion1.addAnnotation("@Override");
        addCriterion1.setName("addCriterion");
        addCriterion1.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "condition"));
        addCriterion1.addBodyLine("super.addCriterion(condition);");
        addCriterion1.addBodyLine("addRoot(criteria.size() - 1);");
        innerClass.addMethod(addCriterion1);

        Method addCriterion3 = new Method();
        addCriterion3.setVisibility(JavaVisibility.PROTECTED);
        addCriterion3.addAnnotation("@Override");
        addCriterion3.setName("addCriterion");
        addCriterion3.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "condition"));
        addCriterion3.addParameter(new Parameter(FullyQualifiedJavaType.getObjectInstance(), "value"));
        addCriterion3.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "property"));
        addCriterion3.addBodyLine("super.addCriterion(condition, value, property);");
        addCriterion3.addBodyLine("addRoot(criteria.size() - 1);");
        innerClass.addMethod(addCriterion3);

        Method addCriterion4 = new Method();
        addCriterion4.setVisibility(JavaVisibility.PROTECTED);
        addCriterion4.addAnnotation("@Override");
        addCriterion4.setName("addCriterion");
        addCriterion4.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "condition"));
        addCriterion4.addParameter(new Parameter(FullyQualifiedJavaType.getObjectInstance(), "value1"));
        addCriterion4.addParameter(new Parameter(FullyQualifiedJavaType.getObjectInstance(), "value2"));
        addCriterion4.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "property"));
        addCriterion4.addBodyLine("super.addCriterion(condition, value1, value2, property);");
        addCriterion4.addBodyLine("addRoot(criteria.size() - 1);");
        innerClass.addMethod(addCriterion4);


        Method isValid = new Method();
        isValid.setVisibility(JavaVisibility.PUBLIC);
        isValid.addAnnotation("@Override");
        isValid.setName("isValid");
        isValid.setReturnType(FullyQualifiedJavaType.getBooleanPrimitiveInstance());
        isValid.addBodyLine("for (Criterion criterion : criteria) {");
        isValid.addBodyLine("if(!(criterion instanceof OpCriterion)){");
        isValid.addBodyLine("return true;");
        isValid.addBodyLine("}");
        isValid.addBodyLine("}");
        isValid.addBodyLine("return false;");
        innerClass.addMethod(isValid);

        topLevelClass.addInnerClass(innerClass);
        return innerClass;
    }

    //给Criteria加or方法
    private void addCriteriaOrMethod(TopLevelClass topLevelClass) {

        InnerClass criteria = null;
        // first, find the Criteria inner class
        for (InnerClass innerClass : topLevelClass.getInnerClasses()) {
            if ("Criteria".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$
                criteria = innerClass;
                break;
            }
        }

        if (criteria == null) {
            throw new RuntimeException("GeneratedCriteria not exist");
        }

        Method or = new Method();
        or.setVisibility(JavaVisibility.PUBLIC);
        or.setName("openOrCriteria");
        or.setReturnType(new FullyQualifiedJavaType("OrCriteria"));
        or.addBodyLine("OrCriterion orCriterion = new OrCriterion();");
        or.addBodyLine("this.criteria.add(orCriterion);");
        or.addBodyLine("OrCriteria orCriteria = new OrCriteria(this, orCriterion);");
        or.addBodyLine("orCriterion.setCriteria(orCriteria);");
        or.addBodyLine("return orCriteria;");
        criteria.addMethod(or);

    }


    //                java.util.Stack<Criterion> stack = new java.util.Stack();
    //                for (int j = 0; j <= criterions.size(); j++) {
    //                    if (j == criterions.size()) {
    //                        for (Criterion c : stack) {
    //                            sb.append(")");
    //                        }
    //                        stack.clear();
    //                        continue;
    //                    }
    //                    Criterion criterion = criterions.get(j);
    //                    if (criterion instanceof ManExample.OpCriterion) {
    //                        ManExample.OpCriterion opCriterion = (ManExample.OpCriterion) criterion;
    //                        if (opCriterion.getCriteria().isValid()) {
    //                            if(!stack.isEmpty()){
    //                                Criterion sCriterion = stack.peek();
    //                                ManExample.OpCriterion sOpCriterion = (ManExample.OpCriterion) sCriterion;
    //                                ManExample.AbstractCriteria abstractCriteria = sOpCriterion.getCriteria();
    //                                List<Criterion> criterionList = abstractCriteria.getAllCriteria();
    //                                int index = criterionList.indexOf(criterion);
    //                                if (index < 0) {
    //                                    stack.pop();
    //                                    sb.append(")");
    //                                    j--;
    //                                    continue;
    //                                }
    //                            }
    //                            stack.add(criterion);
    //                            ManExample.GeneratedCriteria root = opCriterion.getCriteria().getRoot();
    //                            Criterion first = opCriterion.getCriteria().getFirst();
    //                            List<Criterion> rootCriterion = root.getAllCriteria();
    //                            int firstIndex = rootCriterion.indexOf(first);
    //                            if (firstIndex > 0) {
    //                                for (int z = firstIndex - 1; z >= 0; z--) {
    //                                    Criterion prev = rootCriterion.get(z);
    //                                    if (prev instanceof ManExample.OpCriterion) {
    //                                        if (((ManExample.OpCriterion) prev).getCriteria().isValid()) {
    //                                            break;
    //                                        }
    //                                    } else {
    //                                        if(root instanceof ManExample.OrCriteria) {
    //                                            sb.append(" or ");
    //                                        }else {
    //                                            sb.append(" and ");
    //                                        }
    //                                        break;
    //                                    }
    //                                }
    //                            }
    //                            sb.append("(");
    //                        }
    //                        continue;
    //                    }
    //
    //                    if (j == 0) {
    //                        //do nothing
    //                    } else if (stack.isEmpty()) {
    //                        sb.append(" and ");
    //                    } else if (stack.peek() instanceof ManExample.OpCriterion) {
    //                        ManExample.OpCriterion opCriterion = (ManExample.OpCriterion) stack.peek();
    //                        ManExample.AbstractCriteria abstractCriteria = opCriterion.getCriteria();
    //                        List<Criterion> criterionList = abstractCriteria.getAllCriteria();
    //                        int index = criterionList.indexOf(criterion);
    //                        if (index == 0) {
    //                            //do nothing
    //                        } else if (index > 0) {
    //                            if (opCriterion instanceof ManExample.AndCriterion) {
    //                                sb.append(" and ");
    //                            } else {
    //                                sb.append(" or ");
    //                            }
    //                        } else {
    //                            stack.pop();
    //                            sb.append(")");
    //                            j--;
    //                            continue;
    //                        }
    //                    }
    /**
     * 重写ApplyWhere方法
     *
     * @param method
     * @param topLevelClass
     * @param introspectedTable
     * @return
     */
    @Override
    public boolean providerApplyWhereMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {

        List<String> lines = method.getBodyLines();
        boolean hasChange = false;
        for (int i = 0, len = lines.size(); i < len; i++) {
            String line = lines.get(i).trim();
            //找到boolean firstCriterion = true;行插入模式代码
            if (line.matches("boolean\\s*firstCriterion\\s*=\\s*true;\\s*")) {
                lines.set(i, "java.util.Stack<Criterion> stack = new java.util.Stack();");
                hasChange = true;
                break;
            }
        }

        if (!hasChange) {
            throw new RuntimeException("boolean firstCriterion = true; not exist");
        }

        final String topClassName = introspectedTable.getExampleType().substring(introspectedTable.getExampleType().lastIndexOf('.') + 1);
        hasChange = false;
        for (int i = 0, len = lines.size(); i < len; i++) {
            String line = lines.get(i).trim();
            //找到boolean firstCriterion = true;行插入模式代码
            if (line.matches("for\\s*\\(\\s*int\\s*j\\s*=\\s*0\\s*;\\s*j\\s*<\\s*criterions\\.size\\(\\)\\s*;\\s*j\\s*\\+\\+\\s*\\)\\s*\\{")) {
                lines.set(i, "for (int j = 0; j <= criterions.size(); j++) {");

                if (lines.get(i + 1).trim().matches("Criterion\\s*criterion\\s*=\\s*criterions\\.get\\(\\s*j\\s*\\)\\s*;")
                        && lines.get(i + 2).trim().matches("if\\s*\\(\\s*firstCriterion\\s*\\)\\s*\\{")
                        && lines.get(i + 3).trim().matches("firstCriterion\\s*=\\s*false\\s*;")
                        && lines.get(i + 4).trim().matches("}\\s*else\\s*\\{")
                        && lines.get(i + 5).trim().matches("sb\\.append\\(\\s*\"\\s+and\\s+\"\\s*\\);")
                        && lines.get(i + 6).trim().matches("}")) {

                } else {
                    throw new RuntimeException("if (firstCriterion) { not exist");
                }
                List<String> handles = new ArrayList<>();
                handles.add("if (criterion instanceof " + topClassName + ".OpCriterion) {");
                handles.add(topClassName + ".OpCriterion opCriterion = (" + topClassName + ".OpCriterion) criterion;");
                handles.add("if (opCriterion.getCriteria().isValid()) {");

                handles.add("if(!stack.isEmpty()){");
                handles.add("Criterion sCriterion = stack.peek();");
                handles.add(topClassName + ".OpCriterion sOpCriterion = (" + topClassName + ".OpCriterion) sCriterion;");
                handles.add(topClassName + ".AbstractCriteria abstractCriteria = sOpCriterion.getCriteria();");
                handles.add("List<Criterion> criterionList = abstractCriteria.getAllCriteria();");
                handles.add("int index = criterionList.indexOf(criterion);");
                handles.add("if (index < 0) {");
                handles.add("stack.pop();");
                handles.add("sb.append(\")\");");
                handles.add("j--;");
                handles.add("continue;");
                handles.add("}");
                handles.add("}");

                handles.add("stack.add(criterion);");
                handles.add(topClassName + ".GeneratedCriteria root = opCriterion.getCriteria().getRoot();");
                handles.add("Criterion first = opCriterion.getCriteria().getFirst();");
                handles.add("List<Criterion> rootCriterion = root.getAllCriteria();");
                handles.add("int firstIndex = rootCriterion.indexOf(first);");
                handles.add("if (firstIndex > 0) {");
                handles.add("for (int z = firstIndex - 1; z >= 0; z--) {");
                handles.add("Criterion prev = rootCriterion.get(z);");
                handles.add("if (prev instanceof " + topClassName + ".OpCriterion) {");
                handles.add("if (((" + topClassName + ".OpCriterion) prev).getCriteria().isValid()) {");
                handles.add("break;");
                handles.add("}");
                handles.add("} else {");
                handles.add("if(root instanceof " + topClassName + ".OrCriteria) {");
                handles.add("sb.append(\" or \");");
                handles.add("}else {");
                handles.add("sb.append(\" and \");");
                handles.add("}");
                handles.add("break;");
                handles.add("}");
                handles.add("}");
                handles.add("}");
                handles.add("sb.append(\"(\");");
                handles.add("}");
                handles.add("continue;");
                handles.add("}");
                handles.add("");

                handles.add("if (j == 0) {");
                handles.add("//do nothing");
                handles.add("} else if (stack.isEmpty()) {");
                handles.add("sb.append(\" and \");");
                handles.add("} else if (stack.peek() instanceof " + topClassName + ".OpCriterion) {");
                handles.add(topClassName + ".OpCriterion opCriterion = (" + topClassName + ".OpCriterion) stack.peek();");
                handles.add(topClassName + ".AbstractCriteria abstractCriteria = opCriterion.getCriteria();");
                handles.add("List<Criterion> criterionList = abstractCriteria.getAllCriteria();");
                handles.add("int index = criterionList.indexOf(criterion);");
                handles.add("if (index == 0) {");
                handles.add("//do nothing");
                handles.add("} else if (index > 0) {");
                handles.add("if (opCriterion instanceof " + topClassName + ".AndCriterion) {");
                handles.add("sb.append(\" and \");");
                handles.add("} else {");
                handles.add("sb.append(\" or \");");
                handles.add("}");
                handles.add("} else {");
                handles.add("stack.pop();");
                handles.add("sb.append(\")\");");
                handles.add("j--;");
                handles.add("continue;");
                handles.add("}");
                handles.add("}");

                lines.remove(i + 6);
                lines.remove(i + 5);
                lines.remove(i + 4);
                lines.remove(i + 3);
                lines.remove(i + 2);
                lines.addAll(i + 2, handles);


                List<String> posts = new ArrayList<>();
                posts.add("if (j == criterions.size()) {");
                posts.add("for (Criterion c : stack) {");
                posts.add("sb.append(\")\");");
                posts.add("}");
                posts.add("stack.clear();");
                posts.add("continue;");
                posts.add("}");
                lines.addAll(i + 1, posts);

                hasChange = true;
                break;
            }
        }
        if (!hasChange) {
            throw new RuntimeException("boolean firstCriterion = true; not exist");
        }
        return true;
    }


}

三、配置插件

<plugin type="com.mk.mybatisgenerator.plugins.OrPlugin"/>
<!--        <plugin type="com.mk.mybatisgenerator.plugins.MySQLMethodPlugin">-->
<!--            &lt;!&ndash;是否开启生成list参数,默认true开启&ndash;&gt;-->
<!--            <property name="LIST_VALUE" value="true"/>-->
<!--            &lt;!&ndash;value参数占位符自定义,默认##value##&ndash;&gt;-->
<!--            <property name="VALUE_NAME" value="$"/>-->
<!--            &lt;!&ndash;column列名占位符自定义,默认##column##&ndash;&gt;-->
<!--            <property name="COLUMN_NAME" value="."/>-->
<!--            &lt;!&ndash;其他定义,name为方法后缀名,属性值为模式&ndash;&gt;-->
<!--            <property name="isEmpty" value=". = ''"/>-->
<!--            <property name="findInSet" value="find_in_set($, .)"/>-->
<!--        </plugin>-->

 

标签:插件,getXmlCriterion,生成器,innerClass,addBodyLine,add,criteria,Mybatis,new
来源: https://blog.csdn.net/moakun/article/details/111826257