From fc0d2adfd7cdd472e4a3555e0962ba41c58b460b Mon Sep 17 00:00:00 2001 From: hewei Date: Fri, 13 Jan 2017 17:54:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=80=BB=E8=BE=91=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generator/plugins/BatchInsertPlugin.java | 2 + .../plugins/ExampleTargetPlugin.java | 2 +- .../plugins/LogicalDeletePlugin.java | 409 ++++++++++++++++++ 3 files changed, 412 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/itfsw/mybatis/generator/plugins/LogicalDeletePlugin.java diff --git a/src/main/java/com/itfsw/mybatis/generator/plugins/BatchInsertPlugin.java b/src/main/java/com/itfsw/mybatis/generator/plugins/BatchInsertPlugin.java index 8fdee91..7abdf35 100644 --- a/src/main/java/com/itfsw/mybatis/generator/plugins/BatchInsertPlugin.java +++ b/src/main/java/com/itfsw/mybatis/generator/plugins/BatchInsertPlugin.java @@ -71,6 +71,7 @@ public class BatchInsertPlugin extends PluginAdapter { /** * Java Client Methods 生成 * 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html + * * @param interfaze * @param topLevelClass * @param introspectedTable @@ -101,6 +102,7 @@ public class BatchInsertPlugin extends PluginAdapter { /** * SQL Map Methods 生成 * 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html + * * @param document * @param introspectedTable * @return diff --git a/src/main/java/com/itfsw/mybatis/generator/plugins/ExampleTargetPlugin.java b/src/main/java/com/itfsw/mybatis/generator/plugins/ExampleTargetPlugin.java index e111ce2..3e032d7 100644 --- a/src/main/java/com/itfsw/mybatis/generator/plugins/ExampleTargetPlugin.java +++ b/src/main/java/com/itfsw/mybatis/generator/plugins/ExampleTargetPlugin.java @@ -41,7 +41,7 @@ public class ExampleTargetPlugin extends PluginAdapter { public static final String TARGET_PACKAGE_KEY = "targetPackage"; // 配置targetPackage名 private static final Logger logger = LoggerFactory.getLogger(ExampleTargetPlugin.class); - private String targetPackage; // 目标包 + private static String targetPackage; // 目标包 /** * {@inheritDoc} diff --git a/src/main/java/com/itfsw/mybatis/generator/plugins/LogicalDeletePlugin.java b/src/main/java/com/itfsw/mybatis/generator/plugins/LogicalDeletePlugin.java new file mode 100644 index 0000000..d870744 --- /dev/null +++ b/src/main/java/com/itfsw/mybatis/generator/plugins/LogicalDeletePlugin.java @@ -0,0 +1,409 @@ +/* + * 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. + */ + +package com.itfsw.mybatis.generator.plugins; + +import com.itfsw.mybatis.generator.plugins.utils.CommentTools; +import com.itfsw.mybatis.generator.plugins.utils.XmlElementGeneratorTools; +import org.mybatis.generator.api.IntrospectedColumn; +import org.mybatis.generator.api.IntrospectedTable; +import org.mybatis.generator.api.PluginAdapter; +import org.mybatis.generator.api.dom.java.*; +import org.mybatis.generator.api.dom.xml.Attribute; +import org.mybatis.generator.api.dom.xml.Document; +import org.mybatis.generator.api.dom.xml.TextElement; +import org.mybatis.generator.api.dom.xml.XmlElement; +import org.mybatis.generator.codegen.mybatis3.MyBatis3FormattingUtilities; +import org.mybatis.generator.internal.util.StringUtility; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.JDBCType; +import java.util.*; + +/** + * --------------------------------------------------------------------------- + * 逻辑删除插件 + * --------------------------------------------------------------------------- + * @author: hewei + * @time:2017/1/13 14:08 + * --------------------------------------------------------------------------- + */ +public class LogicalDeletePlugin extends PluginAdapter { + private static final Logger logger = LoggerFactory.getLogger(LogicalDeletePlugin.class); + + public static final String METHOD_LOGICAL_DELETE_BY_EXAMPLE = "logicalDeleteByExample"; // 方法名 + public static final String METHOD_LOGICAL_DELETE_BY_PRIMARY_KEY = "logicalDeleteByPrimaryKey"; // 方法名 + + public static final String LOGICAL_DELETE_COLUMN_KEY = "logicalDeleteColumn"; // 逻辑删除列-Key + public static final String LOGICAL_DELETE_VALUE_KEY = "logicalDeleteValue"; // 逻辑删除值-Key + + public static final String DEL_FLAG_NAME = "DEL_FLAG"; // 逻辑删除标志位常量名称 + + public static final String METHOD_LOGICAL_DELETE = "andDeleted"; // 逻辑删除查询方法 + + private IntrospectedColumn logicalDeleteColumn; // 逻辑删除列 + private String logicalDeleteValue; // 逻辑删除值 + + /** + * {@inheritDoc} + */ + @Override + public boolean validate(List warnings) { + // 插件使用前提是targetRuntime为MyBatis3 + if (StringUtility.stringHasValue(getContext().getTargetRuntime()) && "MyBatis3".equalsIgnoreCase(getContext().getTargetRuntime()) == false ){ + logger.warn("itfsw:插件"+this.getClass().getTypeName()+"要求运行targetRuntime必须为MyBatis3!"); + return false; + } + return true; + } + + /** + * 初始化阶段 + * 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html + * + * @param introspectedTable + * @return + */ + @Override + public void initialized(IntrospectedTable introspectedTable) { + // 1. 首先获取全局配置 + Properties properties = getProperties(); + String logicalDeleteColumn = properties.getProperty(LOGICAL_DELETE_COLUMN_KEY); + this.logicalDeleteValue = properties.getProperty(LOGICAL_DELETE_VALUE_KEY); + // 2. 获取表单独配置,如果有则覆盖全局配置 + if (introspectedTable.getTableConfigurationProperty(LOGICAL_DELETE_COLUMN_KEY) != null){ + logicalDeleteColumn = introspectedTable.getTableConfigurationProperty(LOGICAL_DELETE_COLUMN_KEY); + } + if (introspectedTable.getTableConfigurationProperty(LOGICAL_DELETE_VALUE_KEY) != null){ + this.logicalDeleteValue = introspectedTable.getTableConfigurationProperty(LOGICAL_DELETE_VALUE_KEY); + } + // 3. 判断该表是否存在逻辑删除列 + this.logicalDeleteColumn = null; + List columns = introspectedTable.getAllColumns(); + for (IntrospectedColumn column : columns) { + if (column.getActualColumnName().equalsIgnoreCase(logicalDeleteColumn)){ + // 判断字段类型 + JDBCType type = JDBCType.valueOf(column.getJdbcType()); + if (JDBCType.BIGINT == type + || JDBCType.BIT == type + || JDBCType.BOOLEAN == type + || JDBCType.CHAR == type + || JDBCType.DECIMAL == type + || JDBCType.DOUBLE == type + || JDBCType.FLOAT == type + || JDBCType.INTEGER == type + || JDBCType.LONGNVARCHAR == type + || JDBCType.LONGVARCHAR == type + || JDBCType.NCHAR == type + || JDBCType.NUMERIC == type + || JDBCType.NVARCHAR == type + || JDBCType.SMALLINT == type + || JDBCType.TINYINT == type + || JDBCType.VARCHAR == type){ + this.logicalDeleteColumn = column; + } else { + logger.warn("itfsw:插件"+this.getClass().getTypeName()+"逻辑删除列的类型不支持(请使用数字列,字符串列,布尔列)!"); + } + } + } + } + + /** + * Java Client Methods 生成 + * 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html + * + * @param interfaze + * @param topLevelClass + * @param introspectedTable + * @return + */ + @Override + public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { + if (this.logicalDeleteColumn != null){ + // 1. 逻辑删除ByExample + Method mLogicalDeleteByExample = new Method(METHOD_LOGICAL_DELETE_BY_EXAMPLE); + // 返回值类型 + mLogicalDeleteByExample.setReturnType(FullyQualifiedJavaType.getIntInstance()); + // 添加参数 + FullyQualifiedJavaType type = new FullyQualifiedJavaType(introspectedTable.getExampleType()); + mLogicalDeleteByExample.addParameter(new Parameter(type, "example")); + // 添加方法说明 + CommentTools.addGeneralMethodComment(mLogicalDeleteByExample, introspectedTable); + // interface 增加方法 + interfaze.addMethod(mLogicalDeleteByExample); + + // 2. 判断是否有主键,生成主键删除方法 + if (introspectedTable.hasPrimaryKeyColumns()){ + // 1. 逻辑删除ByExample + Method mLogicalDeleteByPrimaryKey = new Method(METHOD_LOGICAL_DELETE_BY_PRIMARY_KEY); + // 返回值类型 + mLogicalDeleteByPrimaryKey.setReturnType(FullyQualifiedJavaType.getIntInstance()); + + // 添加参数 + Set importedTypes = new TreeSet(); + if (introspectedTable.getRules().generatePrimaryKeyClass()) { + FullyQualifiedJavaType type1 = new FullyQualifiedJavaType(introspectedTable.getPrimaryKeyType()); + importedTypes.add(type1); + mLogicalDeleteByPrimaryKey.addParameter(new Parameter(type1, "key")); //$NON-NLS-1$ + } else { + // no primary key class - fields are in the base class + // if more than one PK field, then we need to annotate the + // parameters + // for MyBatis + List introspectedColumns = introspectedTable.getPrimaryKeyColumns(); + boolean annotate = introspectedColumns.size() > 1; + if (annotate) { + importedTypes.add(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Param")); //$NON-NLS-1$ + } + StringBuilder sb = new StringBuilder(); + for (IntrospectedColumn introspectedColumn : introspectedColumns) { + FullyQualifiedJavaType type1 = introspectedColumn.getFullyQualifiedJavaType(); + importedTypes.add(type1); + Parameter parameter = new Parameter(type1, introspectedColumn.getJavaProperty()); + if (annotate) { + sb.setLength(0); + sb.append("@Param(\""); //$NON-NLS-1$ + sb.append(introspectedColumn.getJavaProperty()); + sb.append("\")"); //$NON-NLS-1$ + parameter.addAnnotation(sb.toString()); + } + mLogicalDeleteByPrimaryKey.addParameter(parameter); + } + } + + // 添加方法说明 + CommentTools.addGeneralMethodComment(mLogicalDeleteByPrimaryKey, introspectedTable); + // interface 增加方法 + interfaze.addImportedTypes(importedTypes); + interfaze.addMethod(mLogicalDeleteByPrimaryKey); + } + } + return true; + } + + /** + * SQL Map Methods 生成 + * 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html + * + * @param document + * @param introspectedTable + * @return + */ + @Override + public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) { + if (this.logicalDeleteColumn != null){ + // 1. 逻辑删除ByExample + XmlElement logicalDeleteByExample = new XmlElement("update"); //$NON-NLS-1$ + logicalDeleteByExample.addAttribute(new Attribute("id", METHOD_LOGICAL_DELETE_BY_EXAMPLE)); + logicalDeleteByExample.addAttribute(new Attribute("parameterType", "map")); //$NON-NLS-1$ //$NON-NLS-2$ + CommentTools.addComment(logicalDeleteByExample); + + StringBuilder sb = new StringBuilder(); + sb.append("update "); //$NON-NLS-1$ + sb.append(introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime()); + sb.append(" set "); + // 更新逻辑删除字段 + sb.append(this.logicalDeleteColumn.getActualColumnName()); + sb.append(" = "); + + // 判断字段类型 + JDBCType type = JDBCType.valueOf(this.logicalDeleteColumn.getJdbcType()); + if (this.logicalDeleteValue == null || "NULL".equalsIgnoreCase(this.logicalDeleteValue)){ + sb.append("NULL"); + } else if (JDBCType.CHAR == type + || JDBCType.LONGNVARCHAR == type + || JDBCType.LONGVARCHAR == type + || JDBCType.NCHAR == type + || JDBCType.NVARCHAR == type + || JDBCType.VARCHAR == type){ + sb.append("'"); + sb.append(this.logicalDeleteValue); + sb.append("'"); + } else { + sb.append(this.logicalDeleteValue); + } + + logicalDeleteByExample.addElement(new TextElement(sb.toString())); + + logicalDeleteByExample.addElement(XmlElementGeneratorTools.getUpdateByExampleIncludeElement(introspectedTable)); + document.getRootElement().addElement(logicalDeleteByExample); + + // 2. 判断是否有主键,生成主键删除方法 + if (introspectedTable.hasPrimaryKeyColumns()){ + XmlElement logicalDeleteByPrimaryKey = new XmlElement("update"); //$NON-NLS-1$ + logicalDeleteByPrimaryKey.addAttribute(new Attribute("id", METHOD_LOGICAL_DELETE_BY_PRIMARY_KEY)); + + String parameterClass; + if (introspectedTable.getRules().generatePrimaryKeyClass()) { + parameterClass = introspectedTable.getPrimaryKeyType(); + } else { + // PK fields are in the base class. If more than on PK + // field, then they are coming in a map. + if (introspectedTable.getPrimaryKeyColumns().size() > 1) { + parameterClass = "map"; //$NON-NLS-1$ + } else { + parameterClass = introspectedTable.getPrimaryKeyColumns().get(0).getFullyQualifiedJavaType().toString(); + } + } + logicalDeleteByPrimaryKey.addAttribute(new Attribute("parameterType", parameterClass)); + CommentTools.addComment(logicalDeleteByPrimaryKey); + + StringBuilder sb1 = new StringBuilder(); + sb1.append("update "); //$NON-NLS-1$ + sb1.append(introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime()); + sb1.append(" set "); + // 更新逻辑删除字段 + sb1.append(this.logicalDeleteColumn.getActualColumnName()); + sb1.append(" = "); + + // 判断字段类型 + JDBCType type1 = JDBCType.valueOf(this.logicalDeleteColumn.getJdbcType()); + if (this.logicalDeleteValue == null || "NULL".equalsIgnoreCase(this.logicalDeleteValue)){ + sb1.append("NULL"); + } else if (JDBCType.CHAR == type1 + || JDBCType.LONGNVARCHAR == type1 + || JDBCType.LONGVARCHAR == type1 + || JDBCType.NCHAR == type1 + || JDBCType.NVARCHAR == type1 + || JDBCType.VARCHAR == type1){ + sb1.append("'"); + sb1.append(this.logicalDeleteValue); + sb1.append("'"); + } else { + sb1.append(this.logicalDeleteValue); + } + + logicalDeleteByPrimaryKey.addElement(new TextElement(sb1.toString())); + + boolean and = false; + for (IntrospectedColumn introspectedColumn : introspectedTable.getPrimaryKeyColumns()) { + sb.setLength(0); + if (and) { + sb.append(" and "); //$NON-NLS-1$ + } else { + sb.append("where "); //$NON-NLS-1$ + and = true; + } + + sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn)); + sb.append(" = "); //$NON-NLS-1$ + sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn)); + logicalDeleteByPrimaryKey.addElement(new TextElement(sb.toString())); + } + + document.getRootElement().addElement(logicalDeleteByPrimaryKey); + } + } + return true; + } + + /** + * Model 生成 + * 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html + * + * @param topLevelClass + * @param introspectedTable + * @return + */ + @Override + public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { + if (this.logicalDeleteColumn != null){ + // 添加删除标志位常量 + Field field = new Field(DEL_FLAG_NAME, this.logicalDeleteColumn.getFullyQualifiedJavaType()); + field.setVisibility(JavaVisibility.PUBLIC); + field.setStatic(true); + field.setFinal(true); + + if (this.logicalDeleteValue == null || "NULL".equalsIgnoreCase(this.logicalDeleteValue)){ + field.setInitializationString("null"); + } else if (this.logicalDeleteColumn.getFullyQualifiedJavaType().getShortNameWithoutTypeArguments().equalsIgnoreCase("String")){ + field.setInitializationString("\"" + this.logicalDeleteValue + "\""); + } else if (this.logicalDeleteColumn.getFullyQualifiedJavaType().getShortNameWithoutTypeArguments().equalsIgnoreCase("Boolean")){ + field.setInitializationString((this.logicalDeleteValue.equals("1") || this.logicalDeleteValue.equalsIgnoreCase("true")) ? "true" : "false"); + } else { + field.setInitializationString(this.logicalDeleteValue); + } + CommentTools.addFieldComment(field, introspectedTable); + + // 常量插入到第一位 + ArrayList fields = (ArrayList) topLevelClass.getFields(); + fields.add(0, field); + } + return true; + } + + /** + * ModelExample Methods 生成 + * 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html + * + * @param topLevelClass + * @param introspectedTable + * @return + */ + @Override + public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { + if (this.logicalDeleteColumn != null){ + // 引入 Model类 + FullyQualifiedJavaType model = introspectedTable.getRules().calculateAllFieldsClass(); + topLevelClass.addImportedType(model); + + List innerClasses = topLevelClass.getInnerClasses(); + for (InnerClass innerClass : innerClasses) { + if ("Criteria".equals(innerClass.getType().getShortName())) { + // 增加逻辑删除条件 + Method method = new Method(METHOD_LOGICAL_DELETE); + CommentTools.addGeneralMethodComment(method, introspectedTable); + method.setVisibility(JavaVisibility.PUBLIC); + method.setReturnType(innerClass.getType()); + method.addParameter(new Parameter(FullyQualifiedJavaType.getBooleanPrimitiveInstance(), "deleted")); + + StringBuffer sb = new StringBuffer(); + sb.append("return deleted ? "); + + String modelName = model.getShortName(); + + // 调用EqualTo方法 + StringBuilder equalToMethodName = new StringBuilder(); + equalToMethodName.append(this.logicalDeleteColumn.getJavaProperty()); + equalToMethodName.setCharAt(0, Character.toUpperCase(equalToMethodName.charAt(0))); + equalToMethodName.insert(0, "and"); //$NON-NLS-1$ + equalToMethodName.append("EqualTo"); + sb.append(equalToMethodName); + sb.append("("+modelName + "." + DEL_FLAG_NAME + ")"); + + sb.append(" : "); + + // 调用NotEqualTo 方法 + StringBuilder notEqualToMethodName = new StringBuilder(); + notEqualToMethodName.append(this.logicalDeleteColumn.getJavaProperty()); + notEqualToMethodName.setCharAt(0, Character.toUpperCase(notEqualToMethodName.charAt(0))); + notEqualToMethodName.insert(0, "and"); //$NON-NLS-1$ + notEqualToMethodName.append("NotEqualTo"); + sb.append(notEqualToMethodName); + sb.append("("+modelName + "." + DEL_FLAG_NAME + ")"); + + sb.append(";"); + + method.addBodyLine(sb.toString()); + + innerClass.addMethod(method); + } + } + } + return true; + } +}