瀏覽代碼

Merge pull request #70 from yujunhao8831/master

代码生成策略
qmdx 8 年之前
父節點
當前提交
c4171cbdbb

+ 34 - 19
src/main/java/com/baomidou/mybatisplus/generator/AutoGenerator.java

@@ -15,32 +15,24 @@
  */
 package com.baomidou.mybatisplus.generator;
 
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.ibatis.logging.Log;
-import org.apache.ibatis.logging.LogFactory;
-import org.apache.velocity.Template;
-import org.apache.velocity.VelocityContext;
-import org.apache.velocity.app.Velocity;
-import org.apache.velocity.app.VelocityEngine;
-
 import com.baomidou.mybatisplus.generator.config.ConstVal;
 import com.baomidou.mybatisplus.generator.config.FileOutConfig;
 import com.baomidou.mybatisplus.generator.config.TemplateConfig;
 import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
+import com.baomidou.mybatisplus.generator.config.po.TableField;
 import com.baomidou.mybatisplus.generator.config.po.TableInfo;
 import com.baomidou.mybatisplus.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.toolkit.StringUtils;
+import org.apache.ibatis.logging.Log;
+import org.apache.ibatis.logging.LogFactory;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.app.VelocityEngine;
+
+import java.io.*;
+import java.text.SimpleDateFormat;
+import java.util.*;
 
 /**
  * 生成文件
@@ -145,6 +137,27 @@ public class AutoGenerator extends AbstractGenerator {
             } else {
                 tableInfo.setImportPackages("java.io.Serializable");
             }
+            // Boolean类型is前缀处理
+            if ( config.getStrategyConfig().isEntityBooleanColumnRemoveIsPrefix() ) {
+                for ( TableField field : tableInfo.getFields() ) {
+                    if ( field.getPropertyType().equalsIgnoreCase( "boolean" ) ) {
+                        if ( field.getPropertyName().indexOf( "is" ) != -1 ) {
+                            String noIsPropertyName = field.getPropertyName()
+                                                           .substring( 2, field.getPropertyName().length() );
+                            String firstChar        = noIsPropertyName.substring( 0, 1 ).toLowerCase();
+                            String afterChar        = noIsPropertyName.substring( 1, noIsPropertyName.length() );
+                            field.setPropertyName( config.getStrategyConfig(), firstChar + afterChar );
+                        }
+                    }
+                }
+            }
+            // RequestMapping 连字符风格 user-info
+            if ( config.getStrategyConfig().isControllerMappingHyphenStyle() ) {
+                ctx.put("controllerMappingHyphenStyle", config.getStrategyConfig().isControllerMappingHyphenStyle());
+                ctx.put("controllerMappingHyphen", StringUtils.camelToHyphen( tableInfo.getEntityPath() ));
+            }
+            
+            ctx.put("restControllerStyle", config.getStrategyConfig().isRestControllerStyle());
             ctx.put("package", packageInfo);
             ctx.put("author", config.getGlobalConfig().getAuthor());
             ctx.put("activeRecord", config.getGlobalConfig().isActiveRecord());
@@ -156,6 +169,8 @@ public class AutoGenerator extends AbstractGenerator {
             ctx.put("entity", tableInfo.getEntityName());
             ctx.put("entityColumnConstant", config.getStrategyConfig().isEntityColumnConstant());
             ctx.put("entityBuilderModel", config.getStrategyConfig().isEntityBuilderModel());
+            ctx.put("entityLombokModel", config.getStrategyConfig().isEntityLombokModel());
+            ctx.put("entityBooleanColumnRemoveIsPrefix", config.getStrategyConfig().isEntityBooleanColumnRemoveIsPrefix());
             ctx.put("superEntityClass", superEntityClass);
             ctx.put("superMapperClassPackage", config.getSuperMapperClass());
             ctx.put("superMapperClass", superMapperClass);

+ 60 - 1
src/main/java/com/baomidou/mybatisplus/generator/config/StrategyConfig.java

@@ -101,6 +101,33 @@ public class StrategyConfig {
      */
     private boolean entityBuilderModel = false;
 
+    /**
+     * 【实体】是否为lombok模型(默认 false)<br>
+     * <a href="https://projectlombok.org/">document</a>
+     */
+    private boolean entityLombokModel = false;
+
+    /**
+     * Boolean类型字段是否移除is前缀(默认 false)<br>
+     * 比如 : 数据库字段名称 : 'is_xxx',类型为 : tinyint. 在映射实体的时候则会去掉is,在实体类中映射最终结果为 xxx
+     */
+    private boolean entityBooleanColumnRemoveIsPrefix = false;
+    /**
+     * 生成 <code>@RestController</code> 控制器
+     * <pre>
+     *      <code>@Controller</code> -> <code>@RestController</code>
+     * </pre>
+     */
+    private boolean restControllerStyle          = false;
+    /**
+     * 驼峰转连字符
+     * <pre>
+     *      <code>@RequestMapping("/managerUserActionHistory")</code> -> <code>@RequestMapping("/manager-user-action-history")</code>
+     * </pre>
+     */
+    private boolean controllerMappingHyphenStyle = false;
+   
+
     public void setDbColumnUnderline(boolean dbColumnUnderline) {
         DB_COLUMN_UNDERLINE = dbColumnUnderline;
     }
@@ -114,7 +141,7 @@ public class StrategyConfig {
      * @return
      */
     public boolean isCapitalModeNaming(String word) {
-        return isCapitalMode && StringUtils.isCapitalMode(word);
+        return isCapitalMode && StringUtils.isCapitalMode( word);
     }
 
     /**
@@ -253,4 +280,36 @@ public class StrategyConfig {
     public void setEntityBuilderModel(boolean entityBuilderModel) {
         this.entityBuilderModel = entityBuilderModel;
     }
+
+    public boolean isEntityLombokModel () {
+        return entityLombokModel;
+    }
+
+    public void setEntityLombokModel ( boolean entityLombokModel ) {
+        this.entityLombokModel = entityLombokModel;
+    }
+
+    public boolean isEntityBooleanColumnRemoveIsPrefix () {
+        return entityBooleanColumnRemoveIsPrefix;
+    }
+
+    public void setEntityBooleanColumnRemoveIsPrefix ( boolean entityBooleanColumnRemoveIsPrefix ) {
+        this.entityBooleanColumnRemoveIsPrefix = entityBooleanColumnRemoveIsPrefix;
+    }
+
+    public boolean isRestControllerStyle () {
+        return restControllerStyle;
+    }
+
+    public void setRestControllerStyle ( boolean restControllerStyle ) {
+        this.restControllerStyle = restControllerStyle;
+    }
+
+    public boolean isControllerMappingHyphenStyle () {
+        return controllerMappingHyphenStyle;
+    }
+
+    public void setControllerMappingHyphenStyle ( boolean controllerMappingHyphenStyle ) {
+        this.controllerMappingHyphenStyle = controllerMappingHyphenStyle;
+    }
 }

+ 90 - 5
src/main/java/com/baomidou/mybatisplus/toolkit/StringUtils.java

@@ -15,11 +15,7 @@
  */
 package com.baomidou.mybatisplus.toolkit;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -48,6 +44,10 @@ public class StringUtils {
      */
     public static final String PLACE_HOLDER = "{%s}";
 
+    private static boolean separatorBeforeDigit = false;
+    private static boolean separatorAfterDigit  = true;
+
+
     private StringUtils() {
     }
 
@@ -609,4 +609,89 @@ public class StringUtils {
         }
         return isCharSequence(cls);
     }
+
+    /**
+     * 驼峰转连字符
+     * <pre>
+     *     StringUtils.camelToHyphen( "managerAdminUserService" ) = manager-admin-user-service 
+     * </pre> 
+     * @see <a href="https://github.com/krasa/StringManipulation">document</a>
+     * @param input
+     * @return 以'-'分隔
+     */
+    public static String camelToHyphen(String input) {
+        return wordsToHyphenCase(wordsAndHyphenAndCamelToConstantCase( input ));
+    }
+    
+    private static String wordsAndHyphenAndCamelToConstantCase ( String input ) {
+        boolean _betweenUpperCases = false;
+        boolean containsLowerCase  = containsLowerCase( input );
+
+        StringBuilder buf          = new StringBuilder();
+        char          previousChar = ' ';
+        char[]        chars        = input.toCharArray();
+        for ( int i = 0 ; i < chars.length ; i++ ) {
+            char    c                                 = chars[i];
+            boolean isUpperCaseAndPreviousIsUpperCase = ( Character.isUpperCase( previousChar ) ) && ( Character.isUpperCase(
+                    c ) );
+            boolean isUpperCaseAndPreviousIsLowerCase = ( Character.isLowerCase( previousChar ) ) && ( Character.isUpperCase(
+                    c ) );
+
+            boolean previousIsWhitespace   = Character.isWhitespace( previousChar );
+            boolean lastOneIsNotUnderscore = ( buf.length() > 0 ) && ( buf.charAt( buf.length() - 1 ) != '_' );
+            boolean isNotUnderscore        = c != '_';
+            if ( ( lastOneIsNotUnderscore ) && ( ( isUpperCaseAndPreviousIsLowerCase ) || ( previousIsWhitespace ) || ( ( _betweenUpperCases ) && ( containsLowerCase ) && ( isUpperCaseAndPreviousIsUpperCase ) ) ) ) {
+                buf.append( "_" );
+            } else if ( ( ( separatorAfterDigit ) && ( Character.isDigit( previousChar ) ) && ( Character.isLetter( c ) ) ) || ( ( separatorBeforeDigit ) && ( Character
+                    .isDigit( c ) ) && ( Character.isLetter( previousChar ) ) ) ) {
+                buf.append( '_' );
+            }
+            if ( ( shouldReplace( c ) ) && ( lastOneIsNotUnderscore ) ) {
+                buf.append( '_' );
+            } else if ( ( ! Character.isWhitespace( c ) ) && ( ( isNotUnderscore ) || ( lastOneIsNotUnderscore ) ) ) {
+                buf.append( Character.toUpperCase( c ) );
+            }
+            previousChar = c;
+        }
+        if ( Character.isWhitespace( previousChar ) ) {
+            buf.append( "_" );
+        }
+        return buf.toString();
+    }
+
+    public static boolean containsLowerCase ( String s ) {
+        for ( char c : s.toCharArray() ) {
+            if ( Character.isLowerCase( c ) ) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean shouldReplace ( char c ) {
+        return ( c == '.' ) || ( c == '_' ) || ( c == '-' );
+    }
+
+    private static String wordsToHyphenCase ( String s ) {
+        StringBuilder buf      = new StringBuilder();
+        char          lastChar = 'a';
+        for ( char c : s.toCharArray() ) {
+            if ( ( Character.isWhitespace( lastChar ) ) && ( ! Character.isWhitespace( c ) ) && ( '-' != c ) && ( buf.length() > 0 ) && ( buf
+                    .charAt( buf.length() - 1 ) != '-' ) ) {
+                buf.append( "-" );
+            }
+            if ( '_' == c ) {
+                buf.append( '-' );
+            } else if ( '.' == c ) {
+                buf.append( '-' );
+            } else if ( ! Character.isWhitespace( c ) ) {
+                buf.append( Character.toLowerCase( c ) );
+            }
+            lastChar = c;
+        }
+        if ( Character.isWhitespace( lastChar ) ) {
+            buf.append( "-" );
+        }
+        return buf.toString();
+    }
 }

+ 12 - 2
src/main/resources/templates/controller.java.vm

@@ -1,7 +1,13 @@
 package ${package.Controller};
 
-import org.springframework.stereotype.Controller;
+
 import org.springframework.web.bind.annotation.RequestMapping;
+
+#if(${restControllerStyle})
+import org.springframework.web.bind.annotation.RestController;
+#else
+import org.springframework.stereotype.Controller;
+#end
 #if(${superControllerClassPackage})
 import ${superControllerClassPackage};
 #end
@@ -14,8 +20,12 @@ import ${superControllerClassPackage};
  * @author ${author}
  * @since ${date}
  */
+#if(${restControllerStyle})
+@RestController
+#else
 @Controller
-@RequestMapping("#if(${package.ModuleName})/${package.ModuleName}#end/${table.entityPath}")
+#end
+@RequestMapping("#if(${package.ModuleName})/${package.ModuleName}#end/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end")
 #if(${superControllerClass})
 public class ${table.controllerName} extends ${superControllerClass} {
 #else

+ 9 - 0
src/main/resources/templates/entity.java.vm

@@ -3,6 +3,9 @@ package ${package.Entity};
 #foreach($pkg in ${table.importPackages})
 import ${pkg};
 #end
+#if(${entityLombokModel})
+import lombok.Data;
+#end
 
 /**
  * <p>
@@ -12,6 +15,10 @@ import ${pkg};
  * @author ${author}
  * @since ${date}
  */
+#if(${entityLombokModel})
+@Data
+@Accessors(chain = true)
+#end
 #if(${table.convert})
 @TableName("${table.name}")
 #end
@@ -46,6 +53,7 @@ public class ${entity} implements Serializable {
 	private ${field.propertyType} ${field.propertyName};
 #end
 
+#if(!${entityLombokModel})
 #foreach($field in ${table.fields})
 #if(${field.propertyType.equals("Boolean")})
 #set($getprefix="is")
@@ -68,6 +76,7 @@ public class ${entity} implements Serializable {
 #end
 	}
 #end
+#end
 
 #if(${entityColumnConstant})
 #foreach($field in ${table.fields})

+ 17 - 15
src/test/java/com/baomidou/mybatisplus/test/generator/MysqlGenerator.java

@@ -15,25 +15,20 @@
  */
 package com.baomidou.mybatisplus.test.generator;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
 import com.baomidou.mybatisplus.generator.AutoGenerator;
 import com.baomidou.mybatisplus.generator.InjectionConfig;
-import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
-import com.baomidou.mybatisplus.generator.config.FileOutConfig;
-import com.baomidou.mybatisplus.generator.config.GlobalConfig;
-import com.baomidou.mybatisplus.generator.config.PackageConfig;
-import com.baomidou.mybatisplus.generator.config.StrategyConfig;
-import com.baomidou.mybatisplus.generator.config.TemplateConfig;
+import com.baomidou.mybatisplus.generator.config.*;
 import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
 import com.baomidou.mybatisplus.generator.config.po.TableInfo;
 import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
 import com.baomidou.mybatisplus.generator.config.rules.DbType;
 import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 /**
  * <p>
  * 代码生成器演示
@@ -72,12 +67,15 @@ public class MysqlGenerator {
 
         // 数据源配置
         DataSourceConfig dsc = new DataSourceConfig();
-        dsc.setDbType(DbType.MYSQL);
+        dsc.setDbType( DbType.MYSQL);
         dsc.setTypeConvert(new MySqlTypeConvert() {
             // 自定义数据库表字段类型转换【可选】
             @Override
-            public DbColumnType processTypeConvert(String fieldType) {
+            public DbColumnType processTypeConvert( String fieldType) {
                 System.out.println("转换类型:" + fieldType);
+                // if ( fieldType.toLowerCase().contains( "tinyint" ) ) {
+                //    return DbColumnType.BOOLEAN;
+                // }
                 return super.processTypeConvert(fieldType);
             }
         });
@@ -92,7 +90,7 @@ public class MysqlGenerator {
         // strategy.setCapitalMode(true);// 全局大写命名
         // strategy.setDbColumnUnderline(true);//全局下划线命名
         strategy.setTablePrefix(new String[]{"bmd_", "mp_"});// 此处可以修改为您的表前缀
-        strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略
+        strategy.setNaming( NamingStrategy.underline_to_camel);// 表名生成策略
         // strategy.setInclude(new String[] { "user" }); // 需要生成的表
         // strategy.setExclude(new String[]{"test"}); // 排除生成的表
         // 自定义实体父类
@@ -112,7 +110,11 @@ public class MysqlGenerator {
         // strategy.setEntityColumnConstant(true);
         // 【实体】是否为构建者模型(默认 false)
         // public User setName(String name) {this.name = name; return this;}
-        // strategy.setEntityBuliderModel(true);
+        // strategy.setEntityBuilderModel(true);
+        // 【实体】是否为lombok模型(默认 false)<a href="https://projectlombok.org/">document</a>
+        // strategy.setEntityLombokModel(true);
+        // Boolean类型字段是否移除is前缀处理
+        // strategy.setEntityBooleanColumnRemoveIsPrefix(true);
         mpg.setStrategy(strategy);
 
         // 包配置