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">-->
<!-- <!–是否开启生成list参数,默认true开启–>-->
<!-- <property name="LIST_VALUE" value="true"/>-->
<!-- <!–value参数占位符自定义,默认##value##–>-->
<!-- <property name="VALUE_NAME" value="$"/>-->
<!-- <!–column列名占位符自定义,默认##column##–>-->
<!-- <property name="COLUMN_NAME" value="."/>-->
<!-- <!–其他定义,name为方法后缀名,属性值为模式–>-->
<!-- <property name="isEmpty" value=". = ''"/>-->
<!-- <property name="findInSet" value="find_in_set($, .)"/>-->
<!-- </plugin>-->