diff --git a/README.md b/README.md index 1eaecef..a32c693 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ * Example 目标包修改插件(ExampleTargetPlugin) * 批量插入插件(BatchInsertPlugin) * 逻辑删除插件(LogicalDeletePlugin) +* 数据Model属性对应Column获取插件(ModelColumnPlugin) --------------------------------------- Maven引用: @@ -18,7 +19,7 @@ Maven引用: com.itfsw mybatis-generator-plugin - 1.0.4 + 1.0.5 ``` --------------------------------------- @@ -163,6 +164,7 @@ public class Test { * Criteria的快速返回example()方法。 * Criteria链式调用增强,以前如果有按条件增加的查询语句会打乱链式查询构建,现在有了andIf(boolean ifAdd, CriteriaAdd add)方法可一直使用链式调用下去。 * Example增强了setOrderByClause方法,新增orderBy(String orderByClause)方法直接返回example,增强链式调用,可以一路.下去了。 +* 继续增强orderBy(String orderByClause)方法,增加orderBy(String ... orderByClauses)方法,配合数据Model属性对应Column获取插件(ModelColumnPlugin)使用效果更佳。 插件: ```xml @@ -233,6 +235,8 @@ public class Test { .andField1GreaterThan(1) .example() .orderBy("field1 DESC") + // 这个配合数据Model属性对应Column获取插件(ModelColumnPlugin)使用 + .orderBy(Tb.Column.field1.asc(), Tb.Column.field3.desc()) ); } } @@ -248,7 +252,8 @@ Mybatis Generator 插件默认把Model类和Example类都生成到一个包下 ``` ### 6. 批量插入插件 -提供了一个批量插入batchInsert方法,因为方法使用了使用了JDBC的getGenereatedKeys方法返回插入主键,所以只能在MYSQL和SQLServer下使用。 +提供了一个批量插入batchInsert方法,因为方法使用了使用了JDBC的getGenereatedKeys方法返回插入主键,所以只能在MYSQL和SQLServer下使用。 +建议配合数据Model属性对应Column获取插件(ModelColumnPlugin)插件使用,会把批量插入方法从batchInsert(@Param("list") List list)增强为batchInsert(@Param("list") List list, @Param("insertColumns") Tb.Column ... insertColumns),实现类似于insertSelective插入列! 插件: ```xml @@ -265,7 +270,7 @@ public class Test { .field1(0) .field2("xx0") .field3(0) - .field4(new Date()) + .createTime(new Date()) .build() ); list.add( @@ -273,10 +278,13 @@ public class Test { .field1(1) .field2("xx1") .field3(1) - .field4(new Date()) + .createTime(new Date()) .build() ); + // 普通插入,插入所有列 this.tbMapper.batchInsert(list); + // !!!下面按需插入指定列(类似于insertSelective),需要数据Model属性对应Column获取插件(ModelColumnPlugin)插件 + this.tbMapper.batchInsert(list, Tb.Column.field1, Tb.Column.field2, Tb.Column.field3, Tb.Column.createTime); } } ``` @@ -330,3 +338,64 @@ public class Test { } } ``` +### 8. 数据Model属性对应Column获取插件 +项目中我们有时需要获取数据Model对应数据库字段的名称,一般直接根据数据Model的属性就可以猜出数据库对应column的名字,可是有的时候当column使用了columnOverride或者columnRenamingRule时就需要去看数据库设计了,所以提供了这个插件获取model对应的数据库Column。 +* 配合Example Criteria 增强插件(ExampleEnhancedPlugin)使用,这个插件还提供了asc()和desc()方法配合Example的orderBy方法效果更佳。 +* 配合批量插入插件(BatchInsertPlugin)使用,批量插入会被增强成batchInsert(@Param("list") List list, @Param("insertColumns") XXX.Column ... insertColumns)。 + +插件: +```xml + + +``` +使用: +```java +public class Test { + public static void main(String[] args) { + // 1. 获取Model对应column + String column = Tb.Column.createTime.value(); + + // 2. 配合Example Criteria 增强插件(ExampleEnhancedPlugin)使用orderBy方法 + // old + this.tbMapper.selectByExample( + new TbExample() + .createCriteria() + .andField1GreaterThan(1) + .example() + .orderBy("field1 DESC, field3 ASC") + ); + + // better + this.tbMapper.selectByExample( + new TbExample() + .createCriteria() + .andField1GreaterThan(1) + .example() + .orderBy(Tb.Column.field1.desc(), Tb.Column.field3.asc()) + ); + + // 3. 配合批量插入插件(BatchInsertPlugin)使用实现按需插入指定列 + List list = new ArrayList<>(); + list.add( + new Tb.Builder() + .field1(0) + .field2("xx0") + .field3(0) + .field4(new Date()) + .build() + ); + list.add( + new Tb.Builder() + .field1(1) + .field2("xx1") + .field3(1) + .field4(new Date()) + .build() + ); + // 这个会插入表所有列 + this.tbMapper.batchInsert(list); + // 下面按需插入指定列(类似于insertSelective) + this.tbMapper.batchInsert(list, Tb.Column.field1, Tb.Column.field2, Tb.Column.field3, Tb.Column.createTime); + } +} +``` \ No newline at end of file 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 23c8f2d..71de465 100644 --- a/src/main/java/com/itfsw/mybatis/generator/plugins/BatchInsertPlugin.java +++ b/src/main/java/com/itfsw/mybatis/generator/plugins/BatchInsertPlugin.java @@ -27,7 +27,9 @@ import org.mybatis.generator.api.dom.xml.TextElement; import org.mybatis.generator.api.dom.xml.XmlElement; import org.mybatis.generator.codegen.mybatis3.ListUtilities; import org.mybatis.generator.codegen.mybatis3.MyBatis3FormattingUtilities; +import org.mybatis.generator.config.Context; import org.mybatis.generator.config.GeneratedKey; +import org.mybatis.generator.config.PluginConfiguration; import org.mybatis.generator.internal.util.StringUtility; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,7 +48,7 @@ import java.util.List; public class BatchInsertPlugin extends PluginAdapter { private static final Logger logger = LoggerFactory.getLogger(BatchInsertPlugin.class); public static final String METHOD_BATCH_INSERT = "batchInsert"; // 方法名 - public static final String METHOD_BATCH_INSERT_SELECTIVE = "batchInsertSelective"; // 方法名 + private boolean hasModelBuilderPlugin; // 是否配置了ModelBuilderPlugin插件 /** * {@inheritDoc} @@ -58,6 +60,7 @@ public class BatchInsertPlugin extends PluginAdapter { logger.warn("itfsw:插件" + this.getClass().getTypeName() + "要求运行targetRuntime必须为MyBatis3!"); return false; } + // 插件使用前提是数据库为MySQL或者SQLserver,因为返回主键使用了JDBC的getGenereatedKeys方法获取主键 if ("com.mysql.jdbc.Driver".equalsIgnoreCase(this.getContext().getJdbcConnectionConfiguration().getDriverClass()) == false && "com.microsoft.jdbc.sqlserver.SQLServer".equalsIgnoreCase(this.getContext().getJdbcConnectionConfiguration().getDriverClass()) == false @@ -68,6 +71,33 @@ public class BatchInsertPlugin extends PluginAdapter { return true; } + /** + * 初始化 + * 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html + * + * @param introspectedTable + * @return + */ + @Override + public void initialized(IntrospectedTable introspectedTable) { + // 插件使用前提是使用了ModelColumnPlugin插件 + Context ctx = getContext(); + // 利用反射获取pluginConfigurations属性 + try { + java.lang.reflect.Field field = Context.class.getDeclaredField("pluginConfigurations"); + field.setAccessible(true); + List list = (List) field.get(ctx); + // 检查是否配置了ModelColumnPlugin插件 + for (PluginConfiguration config: list) { + if (ModelColumnPlugin.class.getName().equals(config.getConfigurationType())){ + this.hasModelBuilderPlugin = true; + } + } + } catch (Exception e) { + logger.error(e.getLocalizedMessage()); + } + } + /** * Java Client Methods 生成 * 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html @@ -79,22 +109,41 @@ public class BatchInsertPlugin extends PluginAdapter { */ @Override public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { - // 方法生成 - Method method = new Method(METHOD_BATCH_INSERT); - // 方法可见性 interface会忽略 - // method.setVisibility(JavaVisibility.PUBLIC); - // 返回值类型 - method.setReturnType(FullyQualifiedJavaType.getIntInstance()); - // 添加参数 - FullyQualifiedJavaType type = FullyQualifiedJavaType.getNewListInstance(); - type.addTypeArgument(introspectedTable.getRules().calculateAllFieldsClass()); - method.addParameter(new Parameter(type, "list", "@Param(\"list\")")); - // 添加方法说明 - CommentTools.addGeneralMethodComment(method, introspectedTable); + if (hasModelBuilderPlugin){ + // 方法生成 + Method method = new Method(METHOD_BATCH_INSERT); + // 返回值类型 + method.setReturnType(FullyQualifiedJavaType.getIntInstance()); + // 添加参数 + FullyQualifiedJavaType type = FullyQualifiedJavaType.getNewListInstance(); + type.addTypeArgument(introspectedTable.getRules().calculateAllFieldsClass()); + method.addParameter(new Parameter(type, "list", "@Param(\"list\")")); + FullyQualifiedJavaType type1 = new FullyQualifiedJavaType(introspectedTable.getRules().calculateAllFieldsClass().getShortName()+"."+ModelColumnPlugin.ENUM_NAME); + method.addParameter(new Parameter(type1, "insertColumns", "@Param(\"insertColumns\")", true)); + // 添加方法说明 + CommentTools.addGeneralMethodComment(method, introspectedTable); - // interface 增加方法 - interfaze.addMethod(method); - logger.debug("itfsw(批量插入插件):" + interfaze.getType().getShortName() + "增加batchInsert方法。"); + // interface 增加方法 + interfaze.addMethod(method); + logger.debug("itfsw(批量插入插件):" + interfaze.getType().getShortName() + "增加batchInsert方法。"); + } else { + // 方法生成 + Method method = new Method(METHOD_BATCH_INSERT); + // 方法可见性 interface会忽略 + // method.setVisibility(JavaVisibility.PUBLIC); + // 返回值类型 + method.setReturnType(FullyQualifiedJavaType.getIntInstance()); + // 添加参数 + FullyQualifiedJavaType type = FullyQualifiedJavaType.getNewListInstance(); + type.addTypeArgument(introspectedTable.getRules().calculateAllFieldsClass()); + method.addParameter(new Parameter(type, "list", "@Param(\"list\")")); + // 添加方法说明 + CommentTools.addGeneralMethodComment(method, introspectedTable); + + // interface 增加方法 + interfaze.addMethod(method); + logger.debug("itfsw(批量插入插件):" + interfaze.getType().getShortName() + "增加batchInsert方法。"); + } return true; } @@ -109,39 +158,128 @@ public class BatchInsertPlugin extends PluginAdapter { */ @Override public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) { - // batchInsert - this.generatorBatchInsertXml(document, introspectedTable); + if (hasModelBuilderPlugin){ + XmlElement element = new XmlElement("insert"); + element.addAttribute(new Attribute("id", METHOD_BATCH_INSERT)); + // 参数类型 + element.addAttribute(new Attribute("parameterType", "map")); + // 添加注释(!!!必须添加注释,overwrite覆盖生成时,@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点,例子:@mbg.generated) + CommentTools.addComment(element); + + GeneratedKey gk = introspectedTable.getGeneratedKey(); + if (gk != null) { + IntrospectedColumn introspectedColumn = introspectedTable.getColumn(gk.getColumn()); + // if the column is null, then it's a configuration error. The + // warning has already been reported + if (introspectedColumn != null) { + // 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer + element.addAttribute(new Attribute("useGeneratedKeys", "true")); //$NON-NLS-1$ //$NON-NLS-2$ + element.addAttribute(new Attribute("keyProperty", introspectedColumn.getJavaProperty())); //$NON-NLS-1$ + element.addAttribute(new Attribute("keyColumn", introspectedColumn.getActualColumnName())); //$NON-NLS-1$ + } + } + + // choose 节点 + XmlElement choose = new XmlElement("choose"); + // when 节点 + XmlElement when = new XmlElement("when"); + when.addAttribute(new Attribute("test", "insertColumns.length != 0")); + when.addElement(new TextElement("insert into "+introspectedTable.getFullyQualifiedTableNameAtRuntime()+" (")); + + XmlElement foreachInsertColumns = new XmlElement("foreach"); + foreachInsertColumns.addAttribute(new Attribute("collection", "insertColumns")); + foreachInsertColumns.addAttribute(new Attribute("item", "column")); + foreachInsertColumns.addAttribute(new Attribute("separator", ",")); + foreachInsertColumns.addElement(new TextElement("${column.value}")); + + when.addElement(foreachInsertColumns); + + when.addElement(new TextElement(")")); + + // values + when.addElement(new TextElement("values")); + + // foreach values + XmlElement foreachValues = new XmlElement("foreach"); + foreachValues.addAttribute(new Attribute("collection", "list")); + foreachValues.addAttribute(new Attribute("item", "item")); + foreachValues.addAttribute(new Attribute("separator", ",")); + + foreachValues.addElement(new TextElement("(")); + + // foreach 所有插入的列,比较是否存在 + XmlElement foreachInsertColumnsCheck = new XmlElement("foreach"); + foreachInsertColumnsCheck.addAttribute(new Attribute("collection", "insertColumns")); + foreachInsertColumnsCheck.addAttribute(new Attribute("item", "column")); + foreachInsertColumnsCheck.addAttribute(new Attribute("separator", ",")); + + // 所有表字段 + List columns = ListUtilities.removeIdentityAndGeneratedAlwaysColumns(introspectedTable.getAllColumns()); + for (int i = 0; i < columns.size(); i++) { + IntrospectedColumn introspectedColumn = columns.get(i); + XmlElement check = new XmlElement("if"); + check.addAttribute(new Attribute("test", "'"+introspectedColumn.getActualColumnName()+"' == column.value")); + check.addElement(new TextElement(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn, "item."))); + + foreachInsertColumnsCheck.addElement(check); + } + foreachValues.addElement(foreachInsertColumnsCheck); + + foreachValues.addElement(new TextElement(")")); + + when.addElement(foreachValues); + choose.addElement(when); + + // 普通不带insertColumns参数实现 + XmlElement otherwise = new XmlElement("otherwise"); + this.addNormalBatchInsertXml(otherwise, introspectedTable); + choose.addElement(otherwise); + + element.addElement(choose); + if (context.getPlugins().sqlMapInsertElementGenerated(element, introspectedTable)) { + document.getRootElement().addElement(element); + logger.debug("itfsw(批量插入插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加batchInsert实现方法。"); + } + } else { + XmlElement element = new XmlElement("insert"); //$NON-NLS-1$ + + element.addAttribute(new Attribute("id", METHOD_BATCH_INSERT)); //$NON-NLS-1$ + + // 参数类型 + element.addAttribute(new Attribute("parameterType", FullyQualifiedJavaType.getNewListInstance().getFullyQualifiedName())); + + // 添加注释(!!!必须添加注释,overwrite覆盖生成时,@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点,例子:@mbg.generated) + CommentTools.addComment(element); + + GeneratedKey gk = introspectedTable.getGeneratedKey(); + if (gk != null) { + IntrospectedColumn introspectedColumn = introspectedTable.getColumn(gk.getColumn()); + // if the column is null, then it's a configuration error. The + // warning has already been reported + if (introspectedColumn != null) { + // 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer + element.addAttribute(new Attribute("useGeneratedKeys", "true")); //$NON-NLS-1$ //$NON-NLS-2$ + element.addAttribute(new Attribute("keyProperty", introspectedColumn.getJavaProperty())); //$NON-NLS-1$ + element.addAttribute(new Attribute("keyColumn", introspectedColumn.getActualColumnName())); //$NON-NLS-1$ + } + } + + // 普通插入语句 + this.addNormalBatchInsertXml(element, introspectedTable); + + document.getRootElement().addElement(element); + logger.debug("itfsw(批量插入插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加batchInsert实现方法。"); + } return true; } /** - * 生成BatchInsert对应的xml - * @param document + * 普通不带insertColumns的插入语句Xml实现 + * + * @param element * @param introspectedTable */ - private void generatorBatchInsertXml(Document document, IntrospectedTable introspectedTable) { - XmlElement element = new XmlElement("insert"); //$NON-NLS-1$ - - element.addAttribute(new Attribute("id", METHOD_BATCH_INSERT)); //$NON-NLS-1$ - - // 参数类型 - element.addAttribute(new Attribute("parameterType", FullyQualifiedJavaType.getNewListInstance().getFullyQualifiedName())); - - // 添加注释(!!!必须添加注释,overwrite覆盖生成时,@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点,例子:@mbg.generated) - CommentTools.addComment(element); - - GeneratedKey gk = introspectedTable.getGeneratedKey(); - if (gk != null) { - IntrospectedColumn introspectedColumn = introspectedTable.getColumn(gk.getColumn()); - // if the column is null, then it's a configuration error. The - // warning has already been reported - if (introspectedColumn != null) { - // 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer - element.addAttribute(new Attribute("useGeneratedKeys", "true")); //$NON-NLS-1$ //$NON-NLS-2$ - element.addAttribute(new Attribute("keyProperty", introspectedColumn.getJavaProperty())); //$NON-NLS-1$ - element.addAttribute(new Attribute("keyColumn", introspectedColumn.getActualColumnName())); //$NON-NLS-1$ - } - } + private void addNormalBatchInsertXml(XmlElement element, IntrospectedTable introspectedTable) { StringBuilder insertClause = new StringBuilder(); StringBuilder valuesClause = new StringBuilder(); @@ -187,10 +325,5 @@ public class BatchInsertPlugin extends PluginAdapter { // values 构建 element.addElement(new TextElement("values")); element.addElement(foreachElement); - - if (context.getPlugins().sqlMapInsertElementGenerated(element, introspectedTable)) { - document.getRootElement().addElement(element); - logger.debug("itfsw(批量插入插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加batchInsert实现方法。"); - } } } diff --git a/src/main/java/com/itfsw/mybatis/generator/plugins/ExampleEnhancedPlugin.java b/src/main/java/com/itfsw/mybatis/generator/plugins/ExampleEnhancedPlugin.java index a557921..d5f3778 100644 --- a/src/main/java/com/itfsw/mybatis/generator/plugins/ExampleEnhancedPlugin.java +++ b/src/main/java/com/itfsw/mybatis/generator/plugins/ExampleEnhancedPlugin.java @@ -162,5 +162,25 @@ public class ExampleEnhancedPlugin extends PluginAdapter { CommentTools.addGeneralMethodComment(method, introspectedTable); topLevelClass.addMethod(method); logger.debug("itfsw(Example增强插件):"+topLevelClass.getType().getShortName()+"增加方法orderBy"); + + // 添加orderBy + Method mOrderByMore = new Method("orderBy"); + mOrderByMore.setVisibility(JavaVisibility.PUBLIC); + mOrderByMore.setReturnType(topLevelClass.getType()); + mOrderByMore.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "orderByClauses", true)); + + mOrderByMore.addBodyLine("StringBuffer sb = new StringBuffer();"); + mOrderByMore.addBodyLine("for (int i = 0; i < orderByClauses.length; i++) {"); + mOrderByMore.addBodyLine("sb.append(orderByClauses[i]);"); + mOrderByMore.addBodyLine("if (i < orderByClauses.length - 1) {"); + mOrderByMore.addBodyLine("sb.append(\" , \");"); + mOrderByMore.addBodyLine("}"); + mOrderByMore.addBodyLine("}"); + mOrderByMore.addBodyLine("this.setOrderByClause(sb.toString());"); + mOrderByMore.addBodyLine("return this;"); + + CommentTools.addGeneralMethodComment(mOrderByMore, introspectedTable); + topLevelClass.addMethod(mOrderByMore); + logger.debug("itfsw(Example增强插件):"+topLevelClass.getType().getShortName()+"增加方法orderBy(String ... orderByClauses)"); } } diff --git a/src/main/java/com/itfsw/mybatis/generator/plugins/ModelBuilderPlugin.java b/src/main/java/com/itfsw/mybatis/generator/plugins/ModelBuilderPlugin.java index 41f36b2..315ff01 100644 --- a/src/main/java/com/itfsw/mybatis/generator/plugins/ModelBuilderPlugin.java +++ b/src/main/java/com/itfsw/mybatis/generator/plugins/ModelBuilderPlugin.java @@ -69,20 +69,21 @@ public class ModelBuilderPlugin extends PluginAdapter { InnerClass innerClass = new InnerClass(BUILDER_CLASS_NAME); innerClass.setVisibility(JavaVisibility.PUBLIC); innerClass.setStatic(true); - CommentTools.addClassComment(innerClass, introspectedTable); + CommentTools.addInnerClassComment(innerClass, introspectedTable); logger.debug("itfsw(数据Model链式构建插件):"+topLevelClass.getType().getShortName()+"增加内部Builder类。"); // 构建内部obj变量 Field f = new Field("obj", topLevelClass.getType()); f.setVisibility(JavaVisibility.PRIVATE); + CommentTools.addFieldComment(f, introspectedTable); innerClass.addField(f); // 构造构造方法 Method constructor = new Method(BUILDER_CLASS_NAME); constructor.setVisibility(JavaVisibility.PUBLIC); constructor.setConstructor(true); - constructor.addBodyLine(new StringBuilder("this.obj = new ") - .append(topLevelClass.getType().getShortName()).append("();").toString()); + constructor.addBodyLine(new StringBuilder("this.obj = new ").append(topLevelClass.getType().getShortName()).append("();").toString()); + CommentTools.addGeneralMethodComment(constructor, introspectedTable); innerClass.addMethod(constructor); logger.debug("itfsw(数据Model链式构建插件):"+topLevelClass.getType().getShortName()+".Builder增加的构造方法。"); diff --git a/src/main/java/com/itfsw/mybatis/generator/plugins/ModelColumnPlugin.java b/src/main/java/com/itfsw/mybatis/generator/plugins/ModelColumnPlugin.java new file mode 100644 index 0000000..433e04a --- /dev/null +++ b/src/main/java/com/itfsw/mybatis/generator/plugins/ModelColumnPlugin.java @@ -0,0 +1,137 @@ +/* + * 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 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.internal.util.JavaBeansUtil; +import org.mybatis.generator.internal.util.StringUtility; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * --------------------------------------------------------------------------- + * 数据Model属性对应Column获取插件 + * --------------------------------------------------------------------------- + * @author: hewei + * @time:2017/1/17 11:20 + * --------------------------------------------------------------------------- + */ +public class ModelColumnPlugin extends PluginAdapter { + public static final String ENUM_NAME = "Column"; // 内部Enum名 + private static final Logger logger = LoggerFactory.getLogger(ModelColumnPlugin.class); + + /** + * {@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; + } + + /** + * Model Methods 生成 + * 具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html + * + * @param topLevelClass + * @param introspectedTable + * @return + */ + @Override + public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { + List fields = topLevelClass.getFields(); + + // 生成内部枚举 + InnerEnum innerEnum = new InnerEnum(new FullyQualifiedJavaType(ENUM_NAME)); + innerEnum.setVisibility(JavaVisibility.PUBLIC); + innerEnum.setStatic(true); + CommentTools.addInnerEnumComment(innerEnum, introspectedTable); + logger.debug("itfsw(数据Model属性对应Column获取插件):"+topLevelClass.getType().getShortName()+"增加内部Builder类。"); + + // 生成属性和构造函数 + Field columnField = new Field("column", FullyQualifiedJavaType.getStringInstance()); + columnField.setVisibility(JavaVisibility.PRIVATE); + columnField.setFinal(true); + CommentTools.addFieldComment(columnField, introspectedTable); + innerEnum.addField(columnField); + + Method mValue = new Method("value"); + mValue.setVisibility(JavaVisibility.PUBLIC); + mValue.setReturnType(FullyQualifiedJavaType.getStringInstance()); + mValue.addBodyLine("return this.column;"); + CommentTools.addGeneralMethodComment(mValue, introspectedTable); + innerEnum.addMethod(mValue); + + Method mGetValue = new Method("getValue"); + mGetValue.setVisibility(JavaVisibility.PUBLIC); + mGetValue.setReturnType(FullyQualifiedJavaType.getStringInstance()); + mGetValue.addBodyLine("return this.column;"); + CommentTools.addGeneralMethodComment(mGetValue, introspectedTable); + innerEnum.addMethod(mGetValue); + + Method constructor = new Method(ENUM_NAME); + constructor.setConstructor(true); + constructor.addBodyLine("this.column = column;"); + constructor.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "column")); + CommentTools.addGeneralMethodComment(constructor, introspectedTable); + innerEnum.addMethod(constructor); + logger.debug("itfsw(数据Model属性对应Column获取插件):"+topLevelClass.getType().getShortName()+".Column增加构造方法和column属性。"); + + // Enum枚举 + for (IntrospectedColumn introspectedColumn : introspectedTable.getAllColumns()) { + Field field = JavaBeansUtil.getJavaBeansField(introspectedColumn, context, introspectedTable); + + StringBuffer sb = new StringBuffer(); + sb.append(field.getName()); + sb.append("(\""); + sb.append(introspectedColumn.getActualColumnName()); + sb.append("\")"); + + innerEnum.addEnumConstant(sb.toString()); + logger.debug("itfsw(数据Model属性对应Column获取插件):" + topLevelClass.getType().getShortName() + ".Column增加" + field.getName() + "枚举。"); + } + + // asc 和 desc 方法 + Method desc = new Method("desc"); + desc.setVisibility(JavaVisibility.PUBLIC); + desc.setReturnType(FullyQualifiedJavaType.getStringInstance()); + desc.addBodyLine("return this.column + \" DESC\";"); + CommentTools.addGeneralMethodComment(desc, introspectedTable); + innerEnum.addMethod(desc); + + Method asc = new Method("asc"); + asc.setVisibility(JavaVisibility.PUBLIC); + asc.setReturnType(FullyQualifiedJavaType.getStringInstance()); + asc.addBodyLine("return this.column + \" ASC\";"); + CommentTools.addGeneralMethodComment(asc, introspectedTable); + innerEnum.addMethod(asc); + logger.debug("itfsw(数据Model属性对应Column获取插件):" + topLevelClass.getType().getShortName() + ".Column增加asc()和desc()方法。"); + + topLevelClass.addInnerEnum(innerEnum); + return true; + } +} diff --git a/src/main/java/com/itfsw/mybatis/generator/plugins/utils/CommentTools.java b/src/main/java/com/itfsw/mybatis/generator/plugins/utils/CommentTools.java index 38c5476..38fe627 100644 --- a/src/main/java/com/itfsw/mybatis/generator/plugins/utils/CommentTools.java +++ b/src/main/java/com/itfsw/mybatis/generator/plugins/utils/CommentTools.java @@ -17,10 +17,7 @@ package com.itfsw.mybatis.generator.plugins.utils; import org.mybatis.generator.api.IntrospectedTable; -import org.mybatis.generator.api.dom.java.Field; -import org.mybatis.generator.api.dom.java.InnerClass; -import org.mybatis.generator.api.dom.java.Interface; -import org.mybatis.generator.api.dom.java.Method; +import org.mybatis.generator.api.dom.java.*; import org.mybatis.generator.api.dom.xml.TextElement; import org.mybatis.generator.api.dom.xml.XmlElement; import org.mybatis.generator.config.MergeConstants; @@ -62,7 +59,7 @@ public class CommentTools { * @param innerClass 类 * @param introspectedTable 表 */ - public static void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) { + public static void addInnerClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) { StringBuilder sb = new StringBuilder(); innerClass.addJavaDocLine("/**"); //$NON-NLS-1$ innerClass.addJavaDocLine(" * 这是Mybatis Generator拓展插件生成的类(请勿删除)."); //$NON-NLS-1$ @@ -75,6 +72,25 @@ public class CommentTools { innerClass.addJavaDocLine(" */"); //$NON-NLS-1$ } + /** + * 生成通用内部Enum注释 + * + * @param innerEnum 类 + * @param introspectedTable 表 + */ + public static void addInnerEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) { + StringBuilder sb = new StringBuilder(); + innerEnum.addJavaDocLine("/**"); //$NON-NLS-1$ + innerEnum.addJavaDocLine(" * 这是Mybatis Generator拓展插件生成的枚举(请勿删除)."); //$NON-NLS-1$ + sb.append(" * This class corresponds to the database table "); //$NON-NLS-1$ + sb.append(introspectedTable.getFullyQualifiedTable()); + innerEnum.addJavaDocLine(sb.toString()); + innerEnum.addJavaDocLine(" *"); + innerEnum.addJavaDocLine(" * "+MergeConstants.NEW_ELEMENT_TAG); + innerEnum.addJavaDocLine(" * @author hewei"); + innerEnum.addJavaDocLine(" */"); //$NON-NLS-1$ + } + /** * 生成通用方法注解 *