Commit 1589709d authored by hewei's avatar hewei

pull#12 逻辑删除插件增强

parent b1e23b3b
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
package com.itfsw.mybatis.generator.plugins; package com.itfsw.mybatis.generator.plugins;
import com.itfsw.mybatis.generator.plugins.utils.BasePlugin; import com.itfsw.mybatis.generator.plugins.utils.BasePlugin;
import com.itfsw.mybatis.generator.plugins.utils.FormatTools;
import com.itfsw.mybatis.generator.plugins.utils.JavaElementGeneratorTools; import com.itfsw.mybatis.generator.plugins.utils.JavaElementGeneratorTools;
import com.itfsw.mybatis.generator.plugins.utils.XmlElementGeneratorTools; import com.itfsw.mybatis.generator.plugins.utils.XmlElementGeneratorTools;
import org.mybatis.generator.api.IntrospectedColumn; import org.mybatis.generator.api.IntrospectedColumn;
...@@ -27,10 +28,13 @@ import org.mybatis.generator.api.dom.xml.Document; ...@@ -27,10 +28,13 @@ import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.TextElement; import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement; import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.codegen.mybatis3.MyBatis3FormattingUtilities; import org.mybatis.generator.codegen.mybatis3.MyBatis3FormattingUtilities;
import org.mybatis.generator.internal.util.JavaBeansUtil;
import java.sql.JDBCType; import java.sql.JDBCType;
import java.util.*; import java.util.*;
import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;
/** /**
* --------------------------------------------------------------------------- * ---------------------------------------------------------------------------
* 逻辑删除插件 * 逻辑删除插件
...@@ -52,7 +56,10 @@ public class LogicalDeletePlugin extends BasePlugin { ...@@ -52,7 +56,10 @@ public class LogicalDeletePlugin extends BasePlugin {
public static final String DEFAULT_LOGICAL_DELETE_CONST_NAME = "IS_DELETED"; // 逻辑删除标志位常量名称 public static final String DEFAULT_LOGICAL_DELETE_CONST_NAME = "IS_DELETED"; // 逻辑删除标志位常量名称
public static final String DEFAULT_LOGICAL_UN_DELETE_CONST_NAME = "NOT_DELETED"; // 逻辑删除标志位常量名称(未删除) public static final String DEFAULT_LOGICAL_UN_DELETE_CONST_NAME = "NOT_DELETED"; // 逻辑删除标志位常量名称(未删除)
public static final String METHOD_LOGICAL_DELETE = "andDeleted"; // 逻辑删除查询方法 public static final String METHOD_LOGICAL_DELETED = "andLogicalDeleted"; // 逻辑删除查询方法
public static final String PARAMETER_LOGICAL_DELETED = METHOD_LOGICAL_DELETED; // 增强selectByPrimaryKey是参数名称
public static final String METHOD_SELECT_BY_PRIMARY_KEY_WITH_LOGICAL_DELETE = "selectByPrimaryKeyWithLogicalDelete"; // selectByPrimaryKey 的逻辑删除增强
private IntrospectedColumn logicalDeleteColumn; // 逻辑删除列 private IntrospectedColumn logicalDeleteColumn; // 逻辑删除列
private String logicalDeleteValue; // 逻辑删除值 private String logicalDeleteValue; // 逻辑删除值
...@@ -125,6 +132,15 @@ public class LogicalDeletePlugin extends BasePlugin { ...@@ -125,6 +132,15 @@ public class LogicalDeletePlugin extends BasePlugin {
// 5. 获取逻辑删除常量值 // 5. 获取逻辑删除常量值
this.logicalDeleteConstName = properties.getProperty(PRO_LOGICAL_DELETE_CONST_NAME) != null ? properties.getProperty(PRO_LOGICAL_DELETE_CONST_NAME).toUpperCase() : DEFAULT_LOGICAL_DELETE_CONST_NAME; this.logicalDeleteConstName = properties.getProperty(PRO_LOGICAL_DELETE_CONST_NAME) != null ? properties.getProperty(PRO_LOGICAL_DELETE_CONST_NAME).toUpperCase() : DEFAULT_LOGICAL_DELETE_CONST_NAME;
this.logicalUnDeleteConstName = properties.getProperty(PRO_LOGICAL_UN_DELETE_CONST_NAME) != null ? properties.getProperty(PRO_LOGICAL_UN_DELETE_CONST_NAME).toUpperCase() : DEFAULT_LOGICAL_UN_DELETE_CONST_NAME; this.logicalUnDeleteConstName = properties.getProperty(PRO_LOGICAL_UN_DELETE_CONST_NAME) != null ? properties.getProperty(PRO_LOGICAL_UN_DELETE_CONST_NAME).toUpperCase() : DEFAULT_LOGICAL_UN_DELETE_CONST_NAME;
// 6. 防止增强的selectByPrimaryKey中逻辑删除键冲突
if (this.logicalDeleteColumn != null) {
Field logicalDeleteField = JavaBeansUtil.getJavaBeansField(this.logicalDeleteColumn, context, introspectedTable);
if (logicalDeleteField.getName().equals(PARAMETER_LOGICAL_DELETED)) {
this.logicalDeleteColumn = null;
warnings.add("itfsw(逻辑删除插件):" + introspectedTable.getFullyQualifiedTable() + "配置的逻辑删除列和插件保留关键字(" + PARAMETER_LOGICAL_DELETED + ")冲突!");
}
}
} }
/** /**
...@@ -154,17 +170,30 @@ public class LogicalDeletePlugin extends BasePlugin { ...@@ -154,17 +170,30 @@ public class LogicalDeletePlugin extends BasePlugin {
// 2. 判断是否有主键,生成主键删除方法 // 2. 判断是否有主键,生成主键删除方法
if (introspectedTable.hasPrimaryKeyColumns()) { if (introspectedTable.hasPrimaryKeyColumns()) {
// 1. 逻辑删除ByExample // 2.1. 逻辑删除ByExample
Method mLogicalDeleteByPrimaryKey = new Method(METHOD_LOGICAL_DELETE_BY_PRIMARY_KEY); Method mLogicalDeleteByPrimaryKey = JavaElementGeneratorTools.generateMethod(
// 返回值类型 METHOD_LOGICAL_DELETE_BY_PRIMARY_KEY,
mLogicalDeleteByPrimaryKey.setReturnType(FullyQualifiedJavaType.getIntInstance()); JavaVisibility.DEFAULT,
FullyQualifiedJavaType.getIntInstance()
);
commentGenerator.addGeneralMethodComment(mLogicalDeleteByPrimaryKey, introspectedTable);
// 2.2 增强selectByPrimaryKey
Method mSelectByPrimaryKey = JavaElementGeneratorTools.generateMethod(
METHOD_SELECT_BY_PRIMARY_KEY_WITH_LOGICAL_DELETE,
JavaVisibility.DEFAULT,
introspectedTable.getRules().calculateAllFieldsClass()
);
// 添加参数 // 添加参数
Set<FullyQualifiedJavaType> importedTypes = new TreeSet<FullyQualifiedJavaType>(); Set<FullyQualifiedJavaType> importedTypes = new TreeSet<>();
importedTypes.add(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Param"));
if (introspectedTable.getRules().generatePrimaryKeyClass()) { if (introspectedTable.getRules().generatePrimaryKeyClass()) {
FullyQualifiedJavaType type1 = new FullyQualifiedJavaType(introspectedTable.getPrimaryKeyType()); FullyQualifiedJavaType type1 = new FullyQualifiedJavaType(introspectedTable.getPrimaryKeyType());
importedTypes.add(type1); importedTypes.add(type1);
mLogicalDeleteByPrimaryKey.addParameter(new Parameter(type1, "key")); //$NON-NLS-1$ mLogicalDeleteByPrimaryKey.addParameter(new Parameter(type1, "key"));
mSelectByPrimaryKey.addParameter(new Parameter(type1, "key", "@Param(\"key\")"));
} else { } else {
// no primary key class - fields are in the base class // no primary key class - fields are in the base class
// if more than one PK field, then we need to annotate the // if more than one PK field, then we need to annotate the
...@@ -172,9 +201,6 @@ public class LogicalDeletePlugin extends BasePlugin { ...@@ -172,9 +201,6 @@ public class LogicalDeletePlugin extends BasePlugin {
// for MyBatis // for MyBatis
List<IntrospectedColumn> introspectedColumns = introspectedTable.getPrimaryKeyColumns(); List<IntrospectedColumn> introspectedColumns = introspectedTable.getPrimaryKeyColumns();
boolean annotate = introspectedColumns.size() > 1; boolean annotate = introspectedColumns.size() > 1;
if (annotate) {
importedTypes.add(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Param")); //$NON-NLS-1$
}
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (IntrospectedColumn introspectedColumn : introspectedColumns) { for (IntrospectedColumn introspectedColumn : introspectedColumns) {
FullyQualifiedJavaType type1 = introspectedColumn.getFullyQualifiedJavaType(); FullyQualifiedJavaType type1 = introspectedColumn.getFullyQualifiedJavaType();
...@@ -182,21 +208,38 @@ public class LogicalDeletePlugin extends BasePlugin { ...@@ -182,21 +208,38 @@ public class LogicalDeletePlugin extends BasePlugin {
Parameter parameter = new Parameter(type1, introspectedColumn.getJavaProperty()); Parameter parameter = new Parameter(type1, introspectedColumn.getJavaProperty());
if (annotate) { if (annotate) {
sb.setLength(0); sb.setLength(0);
sb.append("@Param(\""); //$NON-NLS-1$ sb.append("@Param(\"");
sb.append(introspectedColumn.getJavaProperty()); sb.append(introspectedColumn.getJavaProperty());
sb.append("\")"); //$NON-NLS-1$ sb.append("\")");
parameter.addAnnotation(sb.toString()); parameter.addAnnotation(sb.toString());
} }
mLogicalDeleteByPrimaryKey.addParameter(parameter); mLogicalDeleteByPrimaryKey.addParameter(parameter);
Parameter parameter1 = new Parameter(type1, introspectedColumn.getJavaProperty());
sb.setLength(0);
sb.append("@Param(\"");
sb.append(introspectedColumn.getJavaProperty());
sb.append("\")");
parameter1.addAnnotation(sb.toString());
mSelectByPrimaryKey.addParameter(parameter1);
} }
} }
// 添加方法说明
commentGenerator.addGeneralMethodComment(mLogicalDeleteByPrimaryKey, introspectedTable);
// interface 增加方法 // interface 增加方法
interfaze.addImportedTypes(importedTypes); interfaze.addImportedTypes(importedTypes);
interfaze.addMethod(mLogicalDeleteByPrimaryKey); interfaze.addMethod(mLogicalDeleteByPrimaryKey);
logger.debug("itfsw(逻辑删除插件):" + interfaze.getType().getShortName() + "增加方法logicalDeleteByPrimaryKey。"); logger.debug("itfsw(逻辑删除插件):" + interfaze.getType().getShortName() + "增加方法logicalDeleteByPrimaryKey。");
// 增强selectByPrimaryKey
mSelectByPrimaryKey.addParameter(new Parameter(
FullyQualifiedJavaType.getBooleanPrimitiveInstance(),
PARAMETER_LOGICAL_DELETED,
"@Param(\"" + PARAMETER_LOGICAL_DELETED + "\")"
));
commentGenerator.addGeneralMethodComment(mSelectByPrimaryKey, introspectedTable);
FormatTools.addMethodWithBestPosition(interfaze, mSelectByPrimaryKey);
} }
} }
return true; return true;
...@@ -213,13 +256,13 @@ public class LogicalDeletePlugin extends BasePlugin { ...@@ -213,13 +256,13 @@ public class LogicalDeletePlugin extends BasePlugin {
public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) { public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
if (this.logicalDeleteColumn != null) { if (this.logicalDeleteColumn != null) {
// 1. 逻辑删除ByExample // 1. 逻辑删除ByExample
XmlElement logicalDeleteByExample = new XmlElement("update"); //$NON-NLS-1$ XmlElement logicalDeleteByExample = new XmlElement("update");
logicalDeleteByExample.addAttribute(new Attribute("id", METHOD_LOGICAL_DELETE_BY_EXAMPLE)); logicalDeleteByExample.addAttribute(new Attribute("id", METHOD_LOGICAL_DELETE_BY_EXAMPLE));
logicalDeleteByExample.addAttribute(new Attribute("parameterType", "map")); //$NON-NLS-1$ //$NON-NLS-2$ logicalDeleteByExample.addAttribute(new Attribute("parameterType", "map")); //$NON-NLS-2$
commentGenerator.addComment(logicalDeleteByExample); commentGenerator.addComment(logicalDeleteByExample);
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("update "); //$NON-NLS-1$ sb.append("update ");
sb.append(introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime()); sb.append(introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime());
sb.append(" set "); sb.append(" set ");
// 更新逻辑删除字段 // 更新逻辑删除字段
...@@ -251,7 +294,7 @@ public class LogicalDeletePlugin extends BasePlugin { ...@@ -251,7 +294,7 @@ public class LogicalDeletePlugin extends BasePlugin {
// 2. 判断是否有主键,生成主键删除方法 // 2. 判断是否有主键,生成主键删除方法
if (introspectedTable.hasPrimaryKeyColumns()) { if (introspectedTable.hasPrimaryKeyColumns()) {
XmlElement logicalDeleteByPrimaryKey = new XmlElement("update"); //$NON-NLS-1$ XmlElement logicalDeleteByPrimaryKey = new XmlElement("update");
logicalDeleteByPrimaryKey.addAttribute(new Attribute("id", METHOD_LOGICAL_DELETE_BY_PRIMARY_KEY)); logicalDeleteByPrimaryKey.addAttribute(new Attribute("id", METHOD_LOGICAL_DELETE_BY_PRIMARY_KEY));
String parameterClass; String parameterClass;
...@@ -261,7 +304,7 @@ public class LogicalDeletePlugin extends BasePlugin { ...@@ -261,7 +304,7 @@ public class LogicalDeletePlugin extends BasePlugin {
// PK fields are in the base class. If more than on PK // PK fields are in the base class. If more than on PK
// field, then they are coming in a map. // field, then they are coming in a map.
if (introspectedTable.getPrimaryKeyColumns().size() > 1) { if (introspectedTable.getPrimaryKeyColumns().size() > 1) {
parameterClass = "map"; //$NON-NLS-1$ parameterClass = "map";
} else { } else {
parameterClass = introspectedTable.getPrimaryKeyColumns().get(0).getFullyQualifiedJavaType().toString(); parameterClass = introspectedTable.getPrimaryKeyColumns().get(0).getFullyQualifiedJavaType().toString();
} }
...@@ -270,7 +313,7 @@ public class LogicalDeletePlugin extends BasePlugin { ...@@ -270,7 +313,7 @@ public class LogicalDeletePlugin extends BasePlugin {
commentGenerator.addComment(logicalDeleteByPrimaryKey); commentGenerator.addComment(logicalDeleteByPrimaryKey);
StringBuilder sb1 = new StringBuilder(); StringBuilder sb1 = new StringBuilder();
sb1.append("update "); //$NON-NLS-1$ sb1.append("update ");
sb1.append(introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime()); sb1.append(introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime());
sb1.append(" set "); sb1.append(" set ");
// 更新逻辑删除字段 // 更新逻辑删除字段
...@@ -300,25 +343,108 @@ public class LogicalDeletePlugin extends BasePlugin { ...@@ -300,25 +343,108 @@ public class LogicalDeletePlugin extends BasePlugin {
for (IntrospectedColumn introspectedColumn : introspectedTable.getPrimaryKeyColumns()) { for (IntrospectedColumn introspectedColumn : introspectedTable.getPrimaryKeyColumns()) {
sb.setLength(0); sb.setLength(0);
if (and) { if (and) {
sb.append(" and "); //$NON-NLS-1$ sb.append(" and ");
} else { } else {
sb.append("where "); //$NON-NLS-1$ sb.append("where ");
and = true; and = true;
} }
sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn)); sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));
sb.append(" = "); //$NON-NLS-1$ sb.append(" = ");
sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn)); sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn));
logicalDeleteByPrimaryKey.addElement(new TextElement(sb.toString())); logicalDeleteByPrimaryKey.addElement(new TextElement(sb.toString()));
} }
document.getRootElement().addElement(logicalDeleteByPrimaryKey); document.getRootElement().addElement(logicalDeleteByPrimaryKey);
logger.debug("itfsw(逻辑删除插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加方法logicalDeleteByPrimaryKey的实现。"); logger.debug("itfsw(逻辑删除插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加方法logicalDeleteByPrimaryKey的实现。");
// 3. 增强selectByPrimaryKey
XmlElement selectByPrimaryKey = new XmlElement("select");
commentGenerator.addComment(selectByPrimaryKey);
selectByPrimaryKey.addAttribute(new Attribute("id", METHOD_SELECT_BY_PRIMARY_KEY_WITH_LOGICAL_DELETE));
if (introspectedTable.getRules().generateResultMapWithBLOBs()) {
selectByPrimaryKey.addAttribute(new Attribute("resultMap", introspectedTable.getResultMapWithBLOBsId()));
} else {
selectByPrimaryKey.addAttribute(new Attribute("resultMap", introspectedTable.getBaseResultMapId()));
}
selectByPrimaryKey.addAttribute(new Attribute("parameterType", "map"));
context.getCommentGenerator().addComment(selectByPrimaryKey);
sb = new StringBuilder();
sb.append("select ");
if (stringHasValue(introspectedTable.getSelectByPrimaryKeyQueryId())) {
sb.append('\'');
sb.append(introspectedTable.getSelectByPrimaryKeyQueryId());
sb.append("' as QUERYID,");
}
selectByPrimaryKey.addElement(new TextElement(sb.toString()));
selectByPrimaryKey.addElement(XmlElementGeneratorTools.getBaseColumnListElement(introspectedTable));
if (introspectedTable.hasBLOBColumns()) {
selectByPrimaryKey.addElement(new TextElement(","));
selectByPrimaryKey.addElement(XmlElementGeneratorTools.getBlobColumnListElement(introspectedTable));
}
sb.setLength(0);
sb.append("from ");
sb.append(introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime());
selectByPrimaryKey.addElement(new TextElement(sb.toString()));
and = false;
for (IntrospectedColumn introspectedColumn : introspectedTable.getPrimaryKeyColumns()) {
sb.setLength(0);
if (and) {
sb.append(" and ");
} else {
sb.append("where ");
and = true;
}
sb.append(MyBatis3FormattingUtilities.getAliasedEscapedColumnName(introspectedColumn));
sb.append(" = ");
sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn));
selectByPrimaryKey.addElement(new TextElement(sb.toString()));
}
// 逻辑删除的判断
sb.setLength(0);
sb.append(" and ");
sb.append(MyBatis3FormattingUtilities.getAliasedEscapedColumnName(this.logicalDeleteColumn));
sb.append(" = ");
selectByPrimaryKey.addElement(new TextElement(sb.toString()));
XmlElement chooseEle = new XmlElement("choose");
XmlElement whenEle = new XmlElement("when");
whenEle.addAttribute(new Attribute("test", PARAMETER_LOGICAL_DELETED));
whenEle.addElement(new TextElement("'" + this.logicalDeleteValue + "'"));
chooseEle.addElement(whenEle);
XmlElement otherwiseEle = new XmlElement("otherwise");
otherwiseEle.addElement(new TextElement("'" + this.logicalUnDeleteValue + "'"));
chooseEle.addElement(otherwiseEle);
selectByPrimaryKey.addElement(chooseEle);
FormatTools.addElementWithBestPosition(document.getRootElement(), selectByPrimaryKey);
} }
} }
return true; return true;
} }
/**
* 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html
* @param topLevelClass
* @param introspectedTable
* @return
*/
@Override
public boolean modelPrimaryKeyClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
this.generateModelMethodsAndFields(topLevelClass, introspectedTable);
return super.modelPrimaryKeyClassGenerated(topLevelClass, introspectedTable);
}
/** /**
* Model 生成 * Model 生成
* 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html * 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html
...@@ -328,8 +454,28 @@ public class LogicalDeletePlugin extends BasePlugin { ...@@ -328,8 +454,28 @@ public class LogicalDeletePlugin extends BasePlugin {
*/ */
@Override @Override
public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
this.generateModelMethodsAndFields(topLevelClass, introspectedTable);
return super.modelBaseRecordClassGenerated(topLevelClass, introspectedTable);
}
/**
* 生成Model 逻辑删除相关方法和常量
* !!! bugfix:逻辑删除列作为复合主键的一部分的情况
* @param topLevelClass
* @param introspectedTable
*/
private void generateModelMethodsAndFields(TopLevelClass topLevelClass, IntrospectedTable introspectedTable){
if (this.logicalDeleteColumn != null) { if (this.logicalDeleteColumn != null) {
// 常量和逻辑删除方法跟随 逻辑删除列走
boolean flag = false;
for (Field field : topLevelClass.getFields()){
if (this.logicalDeleteColumn.getJavaProperty().equals(field.getName())){
flag = true;
break;
}
}
if (flag){
ArrayList<Field> fields = (ArrayList<Field>) topLevelClass.getFields(); ArrayList<Field> fields = (ArrayList<Field>) topLevelClass.getFields();
// 添加删除标志位常量 // 添加删除标志位常量
...@@ -377,8 +523,20 @@ public class LogicalDeletePlugin extends BasePlugin { ...@@ -377,8 +523,20 @@ public class LogicalDeletePlugin extends BasePlugin {
Field logicalUnDeleteConstField = JavaElementGeneratorTools.generateStaticFinalField(this.logicalUnDeleteConstName, this.logicalDeleteColumn.getFullyQualifiedJavaType(), logicalUnDeleteValue); Field logicalUnDeleteConstField = JavaElementGeneratorTools.generateStaticFinalField(this.logicalUnDeleteConstName, this.logicalDeleteColumn.getFullyQualifiedJavaType(), logicalUnDeleteValue);
commentGenerator.addFieldComment(logicalUnDeleteConstField, introspectedTable); commentGenerator.addFieldComment(logicalUnDeleteConstField, introspectedTable);
fields.add(0, logicalUnDeleteConstField); fields.add(0, logicalUnDeleteConstField);
// ================================================= andLogicalDeleted =============================================
Method mAndLogicalDeleted = JavaElementGeneratorTools.generateMethod(
METHOD_LOGICAL_DELETED,
JavaVisibility.PUBLIC,
null,
new Parameter(FullyQualifiedJavaType.getBooleanPrimitiveInstance(), "deleted")
);
commentGenerator.addGeneralMethodComment(mAndLogicalDeleted, introspectedTable);
Method logicalDeleteSetter = JavaBeansUtil.getJavaBeansSetter(this.logicalDeleteColumn, context, introspectedTable);
mAndLogicalDeleted.addBodyLine(logicalDeleteSetter.getName() +"(deleted ? " + this.logicalDeleteConstName + " : " + this.logicalUnDeleteConstName + ");");
FormatTools.addMethodWithBestPosition(topLevelClass, mAndLogicalDeleted);
}
} }
return true;
} }
/** /**
...@@ -399,7 +557,7 @@ public class LogicalDeletePlugin extends BasePlugin { ...@@ -399,7 +557,7 @@ public class LogicalDeletePlugin extends BasePlugin {
for (InnerClass innerClass : innerClasses) { for (InnerClass innerClass : innerClasses) {
if ("Criteria".equals(innerClass.getType().getShortName())) { if ("Criteria".equals(innerClass.getType().getShortName())) {
// 增加逻辑删除条件 // 增加逻辑删除条件
Method method = new Method(METHOD_LOGICAL_DELETE); Method method = new Method(METHOD_LOGICAL_DELETED);
commentGenerator.addGeneralMethodComment(method, introspectedTable); commentGenerator.addGeneralMethodComment(method, introspectedTable);
method.setVisibility(JavaVisibility.PUBLIC); method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(innerClass.getType()); method.setReturnType(innerClass.getType());
...@@ -414,7 +572,7 @@ public class LogicalDeletePlugin extends BasePlugin { ...@@ -414,7 +572,7 @@ public class LogicalDeletePlugin extends BasePlugin {
StringBuilder equalToMethodName = new StringBuilder(); StringBuilder equalToMethodName = new StringBuilder();
equalToMethodName.append(this.logicalDeleteColumn.getJavaProperty()); equalToMethodName.append(this.logicalDeleteColumn.getJavaProperty());
equalToMethodName.setCharAt(0, Character.toUpperCase(equalToMethodName.charAt(0))); equalToMethodName.setCharAt(0, Character.toUpperCase(equalToMethodName.charAt(0)));
equalToMethodName.insert(0, "and"); //$NON-NLS-1$ equalToMethodName.insert(0, "and");
equalToMethodName.append("EqualTo"); equalToMethodName.append("EqualTo");
sb.append(equalToMethodName); sb.append(equalToMethodName);
sb.append("(" + modelName + "." + this.logicalDeleteConstName + ")"); sb.append("(" + modelName + "." + this.logicalDeleteConstName + ")");
...@@ -425,7 +583,7 @@ public class LogicalDeletePlugin extends BasePlugin { ...@@ -425,7 +583,7 @@ public class LogicalDeletePlugin extends BasePlugin {
StringBuilder notEqualToMethodName = new StringBuilder(); StringBuilder notEqualToMethodName = new StringBuilder();
notEqualToMethodName.append(this.logicalDeleteColumn.getJavaProperty()); notEqualToMethodName.append(this.logicalDeleteColumn.getJavaProperty());
notEqualToMethodName.setCharAt(0, Character.toUpperCase(notEqualToMethodName.charAt(0))); notEqualToMethodName.setCharAt(0, Character.toUpperCase(notEqualToMethodName.charAt(0)));
notEqualToMethodName.insert(0, "and"); //$NON-NLS-1$ notEqualToMethodName.insert(0, "and");
notEqualToMethodName.append("NotEqualTo"); notEqualToMethodName.append("NotEqualTo");
sb.append(notEqualToMethodName); sb.append(notEqualToMethodName);
sb.append("(" + modelName + "." + this.logicalDeleteConstName + ")"); sb.append("(" + modelName + "." + this.logicalDeleteConstName + ")");
...@@ -435,6 +593,12 @@ public class LogicalDeletePlugin extends BasePlugin { ...@@ -435,6 +593,12 @@ public class LogicalDeletePlugin extends BasePlugin {
method.addBodyLine(sb.toString()); method.addBodyLine(sb.toString());
innerClass.addMethod(method); innerClass.addMethod(method);
// TODO 过期方法
Method mAndDeleted = JavaElementGeneratorTools.cloneMethod(method);
mAndDeleted.setName("andDeleted");
mAndDeleted.addAnnotation("@Deprecated");
innerClass.addMethod(mAndDeleted);
logger.debug("itfsw(逻辑删除插件):" + topLevelClass.getType().getShortName() + "." + innerClass.getType().getShortName() + "增加andDeleted方法。"); logger.debug("itfsw(逻辑删除插件):" + topLevelClass.getType().getShortName() + "." + innerClass.getType().getShortName() + "增加andDeleted方法。");
} }
} }
......
...@@ -33,18 +33,17 @@ public class JavaElementGeneratorTools { ...@@ -33,18 +33,17 @@ public class JavaElementGeneratorTools {
/** /**
* 生成静态常量 * 生成静态常量
*
* @param fieldName 常量名称 * @param fieldName 常量名称
* @param javaType 类型 * @param javaType 类型
* @param initString 初始化字段 * @param initString 初始化字段
* @return * @return
*/ */
public static Field generateStaticFinalField(String fieldName, FullyQualifiedJavaType javaType, String initString){ public static Field generateStaticFinalField(String fieldName, FullyQualifiedJavaType javaType, String initString) {
Field field = new Field(fieldName, javaType); Field field = new Field(fieldName, javaType);
field.setVisibility(JavaVisibility.PUBLIC); field.setVisibility(JavaVisibility.PUBLIC);
field.setStatic(true); field.setStatic(true);
field.setFinal(true); field.setFinal(true);
if (initString != null){ if (initString != null) {
field.setInitializationString(initString); field.setInitializationString(initString);
} }
return field; return field;
...@@ -52,17 +51,16 @@ public class JavaElementGeneratorTools { ...@@ -52,17 +51,16 @@ public class JavaElementGeneratorTools {
/** /**
* 生成属性 * 生成属性
*
* @param fieldName 常量名称 * @param fieldName 常量名称
* @param visibility 可见性 * @param visibility 可见性
* @param javaType 类型 * @param javaType 类型
* @param initString 初始化字段 * @param initString 初始化字段
* @return * @return
*/ */
public static Field generateField(String fieldName, JavaVisibility visibility, FullyQualifiedJavaType javaType, String initString){ public static Field generateField(String fieldName, JavaVisibility visibility, FullyQualifiedJavaType javaType, String initString) {
Field field = new Field(fieldName, javaType); Field field = new Field(fieldName, javaType);
field.setVisibility(visibility); field.setVisibility(visibility);
if (initString != null){ if (initString != null) {
field.setInitializationString(initString); field.setInitializationString(initString);
} }
return field; return field;
...@@ -70,19 +68,18 @@ public class JavaElementGeneratorTools { ...@@ -70,19 +68,18 @@ public class JavaElementGeneratorTools {
/** /**
* 生成方法 * 生成方法
*
* @param methodName 方法名 * @param methodName 方法名
* @param visibility 可见性 * @param visibility 可见性
* @param returnType 返回值类型 * @param returnType 返回值类型
* @param parameters 参数列表 * @param parameters 参数列表
* @return * @return
*/ */
public static Method generateMethod(String methodName, JavaVisibility visibility, FullyQualifiedJavaType returnType, Parameter ... parameters){ public static Method generateMethod(String methodName, JavaVisibility visibility, FullyQualifiedJavaType returnType, Parameter... parameters) {
Method method = new Method(methodName); Method method = new Method(methodName);
method.setVisibility(visibility); method.setVisibility(visibility);
method.setReturnType(returnType); method.setReturnType(returnType);
if (parameters != null){ if (parameters != null) {
for (Parameter parameter: parameters) { for (Parameter parameter : parameters) {
method.addParameter(parameter); method.addParameter(parameter);
} }
} }
...@@ -92,14 +89,13 @@ public class JavaElementGeneratorTools { ...@@ -92,14 +89,13 @@ public class JavaElementGeneratorTools {
/** /**
* 生成方法实现体 * 生成方法实现体
*
* @param method 方法 * @param method 方法
* @param bodyLines 方法实现行 * @param bodyLines 方法实现行
* @return * @return
*/ */
public static Method generateMethodBody(Method method, String ... bodyLines){ public static Method generateMethodBody(Method method, String... bodyLines) {
if (bodyLines != null){ if (bodyLines != null) {
for (String bodyLine: bodyLines){ for (String bodyLine : bodyLines) {
method.addBodyLine(bodyLine); method.addBodyLine(bodyLine);
} }
} }
...@@ -108,11 +104,10 @@ public class JavaElementGeneratorTools { ...@@ -108,11 +104,10 @@ public class JavaElementGeneratorTools {
/** /**
* 生成Filed的Set方法 * 生成Filed的Set方法
*
* @param field field * @param field field
* @return * @return
*/ */
public static Method generateSetterMethod(Field field){ public static Method generateSetterMethod(Field field) {
Method method = generateMethod( Method method = generateMethod(
"set" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1), "set" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1),
JavaVisibility.PUBLIC, JavaVisibility.PUBLIC,
...@@ -124,11 +119,10 @@ public class JavaElementGeneratorTools { ...@@ -124,11 +119,10 @@ public class JavaElementGeneratorTools {
/** /**
* 生成Filed的Get方法 * 生成Filed的Get方法
*
* @param field field * @param field field
* @return * @return
*/ */
public static Method generateGetterMethod(Field field){ public static Method generateGetterMethod(Field field) {
Method method = generateMethod( Method method = generateMethod(
"get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1), "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1),
JavaVisibility.PUBLIC, JavaVisibility.PUBLIC,
...@@ -139,11 +133,10 @@ public class JavaElementGeneratorTools { ...@@ -139,11 +133,10 @@ public class JavaElementGeneratorTools {
/** /**
* 获取Model没有BLOBs类时的类型 * 获取Model没有BLOBs类时的类型
*
* @param introspectedTable * @param introspectedTable
* @return * @return
*/ */
public static FullyQualifiedJavaType getModelTypeWithoutBLOBs(IntrospectedTable introspectedTable){ public static FullyQualifiedJavaType getModelTypeWithoutBLOBs(IntrospectedTable introspectedTable) {
FullyQualifiedJavaType type; FullyQualifiedJavaType type;
if (introspectedTable.getRules().generateBaseRecordClass()) { if (introspectedTable.getRules().generateBaseRecordClass()) {
type = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType()); type = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());
...@@ -157,11 +150,10 @@ public class JavaElementGeneratorTools { ...@@ -157,11 +150,10 @@ public class JavaElementGeneratorTools {
/** /**
* 获取Model有BLOBs类时的类型 * 获取Model有BLOBs类时的类型
*
* @param introspectedTable * @param introspectedTable
* @return * @return
*/ */
public static FullyQualifiedJavaType getModelTypeWithBLOBs(IntrospectedTable introspectedTable){ public static FullyQualifiedJavaType getModelTypeWithBLOBs(IntrospectedTable introspectedTable) {
FullyQualifiedJavaType type; FullyQualifiedJavaType type;
if (introspectedTable.getRules().generateRecordWithBLOBsClass()) { if (introspectedTable.getRules().generateRecordWithBLOBsClass()) {
type = new FullyQualifiedJavaType(introspectedTable.getRecordWithBLOBsType()); type = new FullyQualifiedJavaType(introspectedTable.getRecordWithBLOBsType());
...@@ -171,4 +163,28 @@ public class JavaElementGeneratorTools { ...@@ -171,4 +163,28 @@ public class JavaElementGeneratorTools {
} }
return type; return type;
} }
/**
* 克隆方法
* @param method
*/
public static Method cloneMethod(Method method) {
Method result = new Method();
result.setConstructor(method.isConstructor());
result.setFinal(method.isFinal());
result.setName(method.getName());
result.setNative(method.isNative());
result.setReturnType(method.getReturnType());
result.setSynchronized(method.isSynchronized());
result.setStatic(method.isStatic());
result.setVisibility(method.getVisibility());
for (Parameter parameter : method.getParameters()) {
result.addParameter(parameter);
}
for (String docLine : method.getJavaDocLines()){
result.addJavaDocLine(docLine);
}
result.addBodyLines(method.getBodyLines());
return result;
}
} }
...@@ -68,6 +68,12 @@ public class LogicalDeletePluginTest { ...@@ -68,6 +68,12 @@ public class LogicalDeletePluginTest {
tool.generate(); tool.generate();
Assert.assertEquals(tool.getWarnings().get(0), "itfsw(逻辑删除插件):tb没有找到您配置的逻辑删除值,请全局或者局部配置logicalDeleteValue和logicalUnDeleteValue值!"); Assert.assertEquals(tool.getWarnings().get(0), "itfsw(逻辑删除插件):tb没有找到您配置的逻辑删除值,请全局或者局部配置logicalDeleteValue和logicalUnDeleteValue值!");
// 4. 保留关键词冲突
tool = MyBatisGeneratorTool.create("scripts/LogicalDeletePlugin/mybatis-generator-with-keywords.xml");
tool.generate();
Assert.assertEquals(tool.getWarnings().get(0), "itfsw(逻辑删除插件):tb配置的逻辑删除列和插件保留关键字(andLogicalDeleted)冲突!");
} }
/** /**
...@@ -141,7 +147,7 @@ public class LogicalDeletePluginTest { ...@@ -141,7 +147,7 @@ public class LogicalDeletePluginTest {
// 验证sql // 验证sql
String sql = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "selectByExample", tbExample.getObject()); String sql = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "selectByExample", tbExample.getObject());
Assert.assertEquals(sql, "select id, del_flag, ts_1, ts_3, ts_4 from tb WHERE ( del_flag = '1' and id = '3' )"); Assert.assertEquals(sql, "select id, del_flag, and_logical_deleted, ts_1, ts_3, ts_4 from tb WHERE ( del_flag = '1' and id = '3' )");
// 验证执行 // 验证执行
Object result = tbMapper.invoke("selectByExample", tbExample.getObject()); Object result = tbMapper.invoke("selectByExample", tbExample.getObject());
Assert.assertEquals(((List)result).size(), 1); Assert.assertEquals(((List)result).size(), 1);
...@@ -168,11 +174,56 @@ public class LogicalDeletePluginTest { ...@@ -168,11 +174,56 @@ public class LogicalDeletePluginTest {
// 验证sql // 验证sql
String sql = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "selectByExample", tbExample.getObject()); String sql = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "selectByExample", tbExample.getObject());
Assert.assertEquals(sql, "select id, del_flag, ts_1, ts_3, ts_4 from tb WHERE ( del_flag = '0' and id = '3' )"); Assert.assertEquals(sql, "select id, del_flag, and_logical_deleted, ts_1, ts_3, ts_4 from tb WHERE ( del_flag = '0' and id = '3' )");
// 验证执行 // 验证执行
Object result = tbMapper.invoke("selectByExample", tbExample.getObject()); Object result = tbMapper.invoke("selectByExample", tbExample.getObject());
Assert.assertEquals(((List)result).size(), 0); Assert.assertEquals(((List)result).size(), 0);
} }
}); });
} }
/**
* 测试Model andLogicalDeleted 方法
*/
@Test
public void testModelAndLogicalDeletedMethod() throws InterruptedException, SQLException, InvalidConfigurationException, IOException, XMLParserException {
MyBatisGeneratorTool tool = MyBatisGeneratorTool.create("scripts/LogicalDeletePlugin/mybatis-generator-with-customConstName.xml");
tool.generate(new AbstractShellCallback() {
@Override
public void reloadProject(SqlSession sqlSession, ClassLoader loader, String packagz) throws Exception{
ObjectUtil Tb = new ObjectUtil(loader, packagz + ".Tb");
Tb.invoke("andLogicalDeleted", true);
Assert.assertEquals(Tb.get("delFlag"), (short)1);
Tb.invoke("andLogicalDeleted", false);
Assert.assertEquals(Tb.get("delFlag"), (short)0);
}
});
}
/**
* 测试 selectByPrimaryKeyWithLogicalDelete
*/
@Test
public void testSelectByPrimaryKeyWithLogicalDelete() throws IOException, XMLParserException, InvalidConfigurationException, InterruptedException, SQLException {
MyBatisGeneratorTool tool = MyBatisGeneratorTool.create("scripts/LogicalDeletePlugin/mybatis-generator-with-customConstName.xml");
tool.generate(new AbstractShellCallback() {
@Override
public void reloadProject(SqlSession sqlSession, ClassLoader loader, String packagz) throws Exception{
ObjectUtil tbMapper = new ObjectUtil(sqlSession.getMapper(loader.loadClass(packagz + ".TbMapper")));
// 验证sql
String sql = SqlHelper.getFormatMapperSql(tbMapper.getObject(), "selectByPrimaryKeyWithLogicalDelete", 5l, true);
Assert.assertEquals(sql, "select id, del_flag, and_logical_deleted, ts_1, ts_3, ts_4 , ts_2 from tb where id = 5 and del_flag = '1'");
// 验证执行
Object result = tbMapper.invoke("selectByPrimaryKeyWithLogicalDelete", 5l, true);
Assert.assertNull(result);
// 验证执行
result = tbMapper.invoke("selectByPrimaryKeyWithLogicalDelete", 5l, false);
Assert.assertNotNull(result);
}
});
}
} }
...@@ -22,6 +22,7 @@ DROP TABLE IF EXISTS `tb`; ...@@ -22,6 +22,7 @@ DROP TABLE IF EXISTS `tb`;
CREATE TABLE `tb` ( CREATE TABLE `tb` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '注释1', `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '注释1',
`del_flag` smallint(1) NOT NULL DEFAULT '0', `del_flag` smallint(1) NOT NULL DEFAULT '0',
`and_logical_deleted` smallint(1) NOT NULL DEFAULT '0',
`ts_1` tinyint(1) DEFAULT NULL, `ts_1` tinyint(1) DEFAULT NULL,
`ts_2` binary(255) DEFAULT NULL, `ts_2` binary(255) DEFAULT NULL,
`ts_3` float DEFAULT NULL, `ts_3` float DEFAULT NULL,
...@@ -32,6 +33,7 @@ CREATE TABLE `tb` ( ...@@ -32,6 +33,7 @@ CREATE TABLE `tb` (
-- ---------------------------- -- ----------------------------
-- Records of tb -- Records of tb
-- ---------------------------- -- ----------------------------
INSERT INTO `tb` VALUES ('1', '0', null, 0x300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, null, null); INSERT INTO `tb` VALUES ('1', '0', '0', null, 0x300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, null, null);
INSERT INTO `tb` VALUES ('2', '0', null, 0x300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, null, null); INSERT INTO `tb` VALUES ('2', '0', '1', null, 0x300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, null, null);
INSERT INTO `tb` VALUES ('3', '1', null, 0x300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, null, null); INSERT INTO `tb` VALUES ('3', '1', '0', null, 0x300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, null, null);
INSERT INTO `tb` VALUES ('5', '0', '0', null, 0x300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, null, null);
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2017.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<properties resource="db.properties"/>
<!--导入属性配置 -->
<context id="default" targetRuntime="MyBatis3">
<!-- 插件 -->
<plugin type="com.itfsw.mybatis.generator.plugins.LogicalDeletePlugin">
<property name="logicalDeleteColumn" value="and_logical_deleted"/>
<property name="logicalDeleteValue" value="1"/>
<property name="logicalUnDeleteValue" value="0"/>
</plugin>
<!--jdbc的数据库连接 -->
<jdbcConnection driverClass="${driver}" connectionURL="${url}" userId="${username}" password="${password}" />
<!-- Model模型生成器,用来生成含有主键key的类,记录类 以及查询Example类
targetPackage 指定生成的model生成所在的包名
targetProject 指定在该项目下所在的路径 -->
<javaModelGenerator targetPackage="" targetProject=""/>
<!--Mapper映射文件生成所在的目录 为每一个数据库的表生成对应的SqlMap文件 -->
<sqlMapGenerator targetPackage="" targetProject="" />
<!-- 客户端代码,生成易于使用的针对Model对象和XML配置文件 的代码
type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象
type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象
type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口 -->
<javaClientGenerator targetPackage="" targetProject="" type="XMLMAPPER"/>
<!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 要自动生成的表 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<table tableName="tb">
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
</table>
</context>
</generatorConfiguration>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment