├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── build.sh ├── pom.xml └── src └── main ├── java └── com │ └── flyer │ └── maker │ ├── App.java │ ├── base │ ├── Clazz.java │ ├── Config.java │ ├── ConfigSupport.java │ └── Field.java │ ├── freemarker │ ├── FreemarkerConfig.java │ └── templete │ │ ├── ArithUtil.ftl │ │ ├── ArithUtilTest.ftl │ │ ├── BaseController.ftl │ │ ├── BaseResponse.ftl │ │ ├── BeanFactoryRegister.ftl │ │ ├── BeanFactoryRegisterTest.ftl │ │ ├── BizException.ftl │ │ ├── CommonController.ftl │ │ ├── CommonControllerTest.ftl │ │ ├── ControllerInterceptor.ftl │ │ ├── DBUtils.ftl │ │ ├── DateUtil.ftl │ │ ├── ErrorEnum.ftl │ │ ├── GlobalExceptionHandler.ftl │ │ ├── HttpLog.ftl │ │ ├── HttpLogHolder.ftl │ │ ├── LogResponseBodyAdvice.ftl │ │ ├── LogbackProfileListener.ftl │ │ ├── db │ │ ├── controllerTemplate.ftl │ │ ├── controllerTestTemplate.ftl │ │ ├── daoTemplate.ftl │ │ ├── daoTestTemplate.ftl │ │ ├── dataTemplate.ftl │ │ ├── entityTemplate.ftl │ │ ├── mapperTemplate.ftl │ │ ├── saveOrUpdateReqTemplate.ftl │ │ ├── serviceImplTemplate.ftl │ │ └── serviceTemplate.ftl │ │ ├── gitIgnore.ftl │ │ ├── gitkeep.ftl │ │ ├── springboot-rest │ │ ├── AbstractMVCTest.ftl │ │ ├── AbstractTest.ftl │ │ ├── App.java.ftl │ │ ├── WebMvcConfig.ftl │ │ ├── application-dev.properties.ftl │ │ ├── application-prod.properties.ftl │ │ ├── application-stage.properties.ftl │ │ ├── application-test.properties.ftl │ │ ├── application.properties.ftl │ │ ├── logback-spring.ftl │ │ ├── logback-test.ftl │ │ ├── pom.ftl │ │ ├── serviceImplTestTemplate.ftl │ │ └── unit_application.properties.ftl │ │ └── springmvc-rest │ │ ├── AbstractMVCTest.ftl │ │ ├── AbstractTest.ftl │ │ ├── dev_config.properties.ftl │ │ ├── dev_logback.ftl │ │ ├── logback-test.ftl │ │ ├── pom.ftl │ │ ├── prod_config.properties.ftl │ │ ├── prod_logback.ftl │ │ ├── serviceImplTestTemplate.ftl │ │ ├── spring-bootstrap.ftl │ │ ├── spring-core.ftl │ │ ├── spring-dao.ftl │ │ ├── spring-profile.ftl │ │ ├── spring-servlet.ftl │ │ ├── stage_config.properties.ftl │ │ ├── stage_logback.ftl │ │ ├── test_config.properties.ftl │ │ ├── test_logback.ftl │ │ ├── unit_config.properties.ftl │ │ └── webxml.ftl │ ├── generator │ ├── Generator.java │ ├── GeneratorFactory.java │ └── impl │ │ ├── BaseGenerator.java │ │ ├── BootPageGenerator.java │ │ ├── BootRestGenerator.java │ │ ├── MvcPageGenerator.java │ │ └── MvcRestGenerator.java │ ├── parser │ ├── Parser.java │ └── impl │ │ └── MySQLParser.java │ └── utils │ ├── DBUtil.java │ ├── FormatUtil.java │ └── GU.java └── resources ├── application.properties └── logback.xml /.gitattributes: -------------------------------------------------------------------------------- 1 | *.ftl linguist-language=java 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### STS ### 2 | .apt_generated 3 | .classpath 4 | .factorypath 5 | .project 6 | .settings 7 | .springBeans 8 | .sts4-cache 9 | 10 | ### IntelliJ IDEA ### 11 | .idea/ 12 | *.iws 13 | *.iml 14 | *.ipr 15 | dependency-reduced-pom.xml 16 | 17 | ### NetBeans ### 18 | /nbproject/private/ 19 | /build/ 20 | /nbbuild/ 21 | /dist/ 22 | /nbdist/ 23 | /.nb-gradle/ 24 | 25 | # Eclipse 26 | .classpath 27 | .project 28 | .settings/ 29 | 30 | # Others 31 | target/ 32 | logs/ 33 | 34 | # Package Files 35 | *.jar 36 | *.war 37 | *.ear 38 | *.DS_Store 39 | *.class 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Jianying Li. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![License](https://img.shields.io/github/license/vancefantasy/flyer-maker.svg)](https://github.com/vancefantasy/flyer-maker/blob/master/LICENSE) 2 | 3 | # flyermaker是什么? 4 | flyermaker是一个Java项目的脚手架工具,支持SpringBoot和SpringFramework,它允许动态生成工程代码和单元测试,同时尝试提供工程搭建、个别场景实现的最佳实践参考,让开发人员在短时间构建易维护、生产可用的服务。 5 | flyermaker的灵感来自于[SPRING INITIALIZR](https://start.spring.io/)和[MyBatis Generator](https://github.com/mybatis/generator)。 6 | 7 | # 集成环境 8 | - Java 8 9 | - SpringBoot2.0.5/SpringFramework4.3.18 10 | - mapper、entity、dao、service、controller及对应单元测试 11 | - 第三方工具(guava,jodd,vjkit,apache commons等),满足缓存(内存)、字符串、日期、json、集合、Http、IO等的日常处理 12 | - 异常处理 13 | - 全局拦截器,记录请求响应日志 14 | - SLF4J/Logback 15 | - 单元测试、Mock测试 16 | 17 | # flyermaker使用指南 18 | 19 | > **注意:flyermaker当前版本要求数据库表有自增主键,且主键名必须为'id'** 20 | 21 | > Windows用户参考[这里](https://github.com/vancefantasy/flyer-maker/issues/4) 22 | 23 | 1. 下载[最新版本](https://github.com/vancefantasy/flyer-maker/releases)并解压 24 | 25 | unzip flyermaker-0.0.1.zip //zip 26 | tar zxvf flyermaker-0.0.1.tar.gz //tar 27 | 28 | 2. 修改配置文件 29 | 30 | 编辑application.properties文件 31 | 32 | 3. 命令行运行 33 | 34 | flyermaker -f application.properties 35 | 36 | ### 配置文件参考 37 | 38 | 字段 |名称 |是否必须 |默认值 |备注 39 | ----------|----------|-------|-----------|----------- 40 | author |作者|否 |flyermaker|例如:vance 41 | target.dir |目标目录|否 |当前目录|例如:/tmp/flyermaker 42 | project.type |项目类型|是 |-|可选springmvc-rest,springboot-rest,springmvc-page,springboot-page 43 | project.groupId |Maven groupId|是 |-|例如:com.flyer 44 | project.artifactId |Maven artifactId|是 |-|例如:flyer-springboot-rest 45 | project.package |包路径|是 |-|例如:com.flyer.springmvc.rest 46 | mysql.jdbc.url |jdbc url|是 |-|例如:jdbc:mysql://localhost:3306/flyer?useUnicode=true&characterEncoding=utf-8&useSSL=false 47 | mysql.username |mysql username|是 |-|例如:flyer_w 48 | mysql.password |mysql password|是 |-|例如:123456 49 | mysql.table.include |表白名单|否 |空|多个以逗号分割,例如:user,order,t2 50 | mysql.table.exclude |表黑名单|否 |空|多个以逗号分割,例如:user,order,t2 51 | mysql.column.exclude |字段黑名单|否 |空|多个以逗号分割,例如:_timestamp,updatetime 52 | 53 | ### 关于项目类型 54 | 55 | - **springmvc-rest** 基于SpringFramework的Rest服务 56 | - **springboot-rest** 基于SpringBoot的Rest服务 57 | - **springmvc-page** 基于SpringFramework的页面服务,暂不支持 58 | - **springboot-page** 基于SpringBoot的页面服务,暂不支持 59 | 60 | ### 关于白名单、黑名单 61 | 白名单和黑名单是互斥的,白名单的优先级高于黑名单。即:如果设置了白名单,只会扫描白名单的表,如果只设置了黑名单,则会过滤掉黑名单中的表,如果同时设置了白名单、黑名单,则只有白名单生效。 62 | 字段黑名单是全局的,用来过滤不想要的字段,例如'_timestamp(ON UPDATE CURRENT_TIMESTAMP)' 63 | 64 | # 单元测试 65 | 66 | 写好单元测试不是一件容易的事,这里分享下自己的经验:多数情况下使用独立的数据库运行单元测试,运行完清空数据库,会是一个明智的选择。事实上,在本项目中,就体现了类似的规则。 67 | >注意:为避免误清空其他环境数据,运行单元测试时会检测数据库实例是否以'_ut'结尾。生成代码后,请把单元测试的配置文件修改下。 68 | 69 | # 模板项目 70 | 这里维护了flyermaker的模板: 71 | - [flyer-springboot-rest](https://github.com/vancefantasy/flyer-springboot-rest) 72 | - [flyer-springmvc-rest](https://github.com/vancefantasy/flyer-springmvc-rest) 73 | 74 | # 贡献代码 75 | 76 | 欢迎提交Pull Request。有意见或建议,请提issue,也可以[邮件](mailto:vance.8807@gmail.com)。 77 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | version=0.0.1 4 | 5 | mvn clean package 6 | 7 | str='#!/bin/sh \n MYSELF=`which "$0" 2>/dev/null` \n [ $? -gt 0 -a -f "$0" ] && MYSELF="./$0" \n java=java \n if test -n "$JAVA_HOME"; then \n java="$JAVA_HOME/bin/java" \n fi \n exec "$java" -Dcli=true $java_args -jar $MYSELF "$@" \n exit 1' 8 | 9 | cd target 10 | 11 | echo -e $str >> flyermaker 12 | 13 | cat flyer-maker.jar >> flyermaker 14 | 15 | chmod +x flyermaker 16 | 17 | cp classes/application.properties . 18 | 19 | zip -r flyermaker-${version}.zip flyermaker application.properties 20 | 21 | tar zcvf flyermaker-${version}.tar.gz flyermaker application.properties 22 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | com.flyer 7 | flyer-maker 8 | 0.0.1 9 | jar 10 | 11 | 1.8 12 | 13 | 14 | 15 | commons-io 16 | commons-io 17 | 2.6 18 | 19 | 20 | commons-cli 21 | commons-cli 22 | 1.4 23 | 24 | 25 | org.apache.commons 26 | commons-lang3 27 | 3.7 28 | 29 | 30 | org.freemarker 31 | freemarker 32 | 2.3.28 33 | 34 | 35 | mysql 36 | mysql-connector-java 37 | 5.1.45 38 | runtime 39 | 40 | 41 | ch.qos.logback 42 | logback-classic 43 | 1.2.3 44 | 45 | 46 | 47 | flyer-maker 48 | 49 | 50 | src/main/resources 51 | 52 | 53 | src/main/java 54 | 55 | **/*.ftl 56 | 57 | 58 | 59 | 60 | 61 | org.apache.maven.plugins 62 | maven-compiler-plugin 63 | 3.7.0 64 | 65 | ${java.version} 66 | ${java.version} 67 | 68 | 69 | 70 | org.apache.maven.plugins 71 | maven-shade-plugin 72 | 3.2.0 73 | 74 | 75 | package 76 | 77 | shade 78 | 79 | 80 | 81 | 83 | com.flyer.maker.App 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/App.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker; 2 | 3 | import com.flyer.maker.base.Config; 4 | import com.flyer.maker.base.ConfigSupport; 5 | import com.flyer.maker.generator.Generator; 6 | import com.flyer.maker.generator.GeneratorFactory; 7 | import org.apache.commons.cli.*; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.io.File; 12 | 13 | /** 14 | * flyermaker入口函数 15 | */ 16 | public class App { 17 | 18 | private final static Logger log = LoggerFactory.getLogger(App.class); 19 | 20 | private static boolean resolveConfig = false; 21 | 22 | private final static String version = "0.0.1"; 23 | 24 | public static void main(String[] args) { 25 | String isCli = System.getProperty("cli"); 26 | if (Boolean.valueOf(isCli)) { 27 | resolveCli(args); 28 | } else { 29 | ConfigSupport.loadConfigFromClasspath(); 30 | resolveConfig = true; 31 | } 32 | 33 | if (resolveConfig) { 34 | long begin = System.currentTimeMillis(); 35 | Generator generator = GeneratorFactory.getGenerator(); 36 | if (generator == null) { 37 | log.error("generator is null"); 38 | return; 39 | } 40 | try { 41 | generator.generate(); 42 | log.info("flyermaker completed in {} ms", System.currentTimeMillis() - begin); 43 | log.info("target dir : {}", Config.targetDir); 44 | } catch (Exception e) { 45 | log.error("generate error", e); 46 | //失败时清理目录 47 | generator.clearIfFail(); 48 | } 49 | 50 | } 51 | } 52 | 53 | private static void resolveCli(String[] args) { 54 | CommandLineParser parser = new DefaultParser(); 55 | CommandLine line = null; 56 | Option fileOption = 57 | Option.builder("f").hasArg().argName("file").desc("config properties file").build(); 58 | Option versionOption = Option.builder("v").desc("print product version").build(); 59 | Option helpOption = Option.builder("h").desc("print this help message").build(); 60 | Options options = new Options(); 61 | options.addOption(fileOption); 62 | options.addOption(versionOption); 63 | options.addOption(helpOption); 64 | try { 65 | line = parser.parse(options, args); 66 | if (line.hasOption(helpOption.getOpt())) { 67 | printHelp(options); 68 | return; 69 | } 70 | if (line.hasOption(versionOption.getOpt())) { 71 | System.out.println("flyermaker version : " + version); 72 | System.out.println( 73 | "build by vance, to learn more about flyermaker, see https://github.com/vancefantasy/flyer-maker"); 74 | return; 75 | } 76 | if (!line.hasOption(fileOption.getOpt())) { 77 | System.out.println("Missing argument for option: " + fileOption.getOpt()); 78 | printHelp(options); 79 | return; 80 | } 81 | String configFile = line.getOptionValue(fileOption.getOpt()); 82 | File file = new File(configFile); 83 | if (!file.exists()) { 84 | System.out.println("config file [" + configFile + "] is not exists"); 85 | return; 86 | } 87 | ConfigSupport.loadConfigFromFile(file); 88 | resolveConfig = true; 89 | } catch (Exception e) { 90 | System.out.println(e.getMessage()); 91 | printHelp(options); 92 | } 93 | } 94 | 95 | private static void printHelp(Options options) { 96 | HelpFormatter formatter = new HelpFormatter(); 97 | formatter.printHelp("flyermaker [-f ] [-h] [-v]", options); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/base/Clazz.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker.base; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 对应一张表 7 | */ 8 | public class Clazz { 9 | /** 10 | * 表名称 11 | */ 12 | private String tableName; 13 | /** 14 | * 表名称(去前缀,全小写) 15 | */ 16 | private String resouceName; 17 | /** 18 | * 类名称(首字母小写) 19 | */ 20 | private String className; 21 | /** 22 | * 类描述 23 | */ 24 | private String desc; 25 | /** 26 | * 类名称(首字母大写) 27 | */ 28 | private String bclassName; 29 | 30 | private String idType; 31 | 32 | private String idTypeSimple; 33 | /** 34 | * 类字段列表(用于生成entity属性) 35 | */ 36 | private List fieldList; 37 | /** 38 | * 类字段列表(用于生成mybatis sql,表所有字段) 39 | */ 40 | private List tablefieldList; 41 | /** 42 | * 类字段列表(用于生成mybatis sql,去除id的所有字段) 43 | */ 44 | private List insertfieldList; 45 | 46 | public String getTableName() { 47 | return tableName; 48 | } 49 | 50 | public void setTableName(String tableName) { 51 | this.tableName = tableName; 52 | } 53 | 54 | public String getResouceName() { 55 | return resouceName; 56 | } 57 | 58 | public void setResouceName(String resouceName) { 59 | this.resouceName = resouceName; 60 | } 61 | 62 | public String getClassName() { 63 | return className; 64 | } 65 | 66 | public void setClassName(String className) { 67 | this.className = className; 68 | } 69 | 70 | public String getDesc() { 71 | return desc; 72 | } 73 | 74 | public void setDesc(String desc) { 75 | this.desc = desc; 76 | } 77 | 78 | public String getBclassName() { 79 | return bclassName; 80 | } 81 | 82 | public void setBclassName(String bclassName) { 83 | this.bclassName = bclassName; 84 | } 85 | 86 | public String getIdType() { 87 | return idType; 88 | } 89 | 90 | public void setIdType(String idType) { 91 | this.idType = idType; 92 | } 93 | 94 | public List getFieldList() { 95 | return fieldList; 96 | } 97 | 98 | public void setFieldList(List fieldList) { 99 | this.fieldList = fieldList; 100 | } 101 | 102 | public List getTablefieldList() { 103 | return tablefieldList; 104 | } 105 | 106 | public void setTablefieldList(List tablefieldList) { 107 | this.tablefieldList = tablefieldList; 108 | } 109 | 110 | public List getInsertfieldList() { 111 | return insertfieldList; 112 | } 113 | 114 | public void setInsertfieldList(List insertfieldList) { 115 | this.insertfieldList = insertfieldList; 116 | } 117 | 118 | public String getIdTypeSimple() { 119 | return idTypeSimple; 120 | } 121 | 122 | public void setIdTypeSimple(String idTypeSimple) { 123 | this.idTypeSimple = idTypeSimple; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/base/Config.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker.base; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | /** 7 | * 配置项 8 | */ 9 | public class Config { 10 | 11 | //properties begin 12 | public static String author = "flyermaker"; 13 | public static String targetDir = System.getProperty("user.dir"); 14 | 15 | public static String projectType = null; 16 | public static String projectGroupId = null; 17 | public static String projectArtifactId = null; 18 | public static String projectPackage = null; 19 | 20 | public static String mysqlJdbcUrl = null; 21 | public static String mysqlUsername = null; 22 | public static String mysqlPassword = null; 23 | //properties end 24 | 25 | public static Set tableIncludeList = new HashSet<>(); 26 | public static Set tableExcludeList = new HashSet<>(); 27 | public static Set columnExcludeList = new HashSet<>(); 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/base/ConfigSupport.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker.base; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.io.File; 8 | import java.io.FileInputStream; 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | import java.util.Properties; 12 | 13 | /** 14 | * 解析配置 15 | */ 16 | public class ConfigSupport { 17 | 18 | private final static Logger log = LoggerFactory.getLogger(ConfigSupport.class); 19 | 20 | public static Properties properties = null; 21 | 22 | public static void loadConfigFromClasspath() { 23 | try { 24 | Properties prop = new Properties(); 25 | InputStream in = 26 | ConfigSupport.class.getClassLoader().getResourceAsStream("application.properties"); 27 | prop.load(in); 28 | properties = prop; 29 | print(); 30 | init(); 31 | } catch (IOException e) { 32 | log.error("load config error", e); 33 | } 34 | } 35 | 36 | public static void loadConfigFromFile(File file) { 37 | try { 38 | InputStream inStream = new FileInputStream(file); 39 | Properties prop = new Properties(); 40 | prop.load(inStream); 41 | properties = prop; 42 | print(); 43 | init(); 44 | } catch (Exception e) { 45 | e.printStackTrace(); 46 | } 47 | } 48 | 49 | private static void print() { 50 | if (properties != null) { 51 | for (String key : properties.stringPropertyNames()) { 52 | log.debug("key: {}, value : {}", key, properties.getProperty(key)); 53 | } 54 | } 55 | } 56 | 57 | private static void init() { 58 | String author = properties.getProperty("author"); 59 | String targetDir = properties.getProperty("target.dir"); 60 | String projectType = properties.getProperty("project.type"); 61 | String projectGroupId = properties.getProperty("project.groupId"); 62 | String projectArtifactId = properties.getProperty("project.artifactId"); 63 | String projectPackage = properties.getProperty("project.package"); 64 | String mysqlJdbcUrl = properties.getProperty("mysql.jdbc.url"); 65 | String mysqlUsername = properties.getProperty("mysql.username"); 66 | String mysqlPassword = properties.getProperty("mysql.password"); 67 | 68 | if (StringUtils.isNotBlank(projectType)) { 69 | Config.projectType = projectType; 70 | } else { 71 | throw new RuntimeException("project.type is null"); 72 | } 73 | 74 | if (StringUtils.isNotBlank(projectGroupId)) { 75 | Config.projectGroupId = projectGroupId; 76 | } else { 77 | throw new RuntimeException("project.groupId is null"); 78 | } 79 | if (StringUtils.isNotBlank(projectArtifactId)) { 80 | Config.projectArtifactId = projectArtifactId; 81 | } else { 82 | throw new RuntimeException("project.artifact is null"); 83 | } 84 | if (StringUtils.isNotBlank(projectPackage)) { 85 | Config.projectPackage = projectPackage; 86 | } else { 87 | throw new RuntimeException("project.package is null"); 88 | } 89 | if (StringUtils.isNotBlank(mysqlJdbcUrl)) { 90 | Config.mysqlJdbcUrl = mysqlJdbcUrl; 91 | } else { 92 | throw new RuntimeException("mysql.jdbc.url is null"); 93 | } 94 | if (StringUtils.isNotBlank(mysqlUsername)) { 95 | Config.mysqlUsername = mysqlUsername; 96 | } else { 97 | throw new RuntimeException("mysql.username is null"); 98 | } 99 | if (StringUtils.isNotBlank(mysqlPassword)) { 100 | Config.mysqlPassword = mysqlPassword; 101 | } else { 102 | throw new RuntimeException("mysql.password is null"); 103 | } 104 | if (StringUtils.isNotBlank(author)) { 105 | Config.author = author; 106 | } 107 | if (StringUtils.isNotBlank(targetDir)) { 108 | Config.targetDir = targetDir; 109 | } 110 | String mysqlTableInclude = properties.getProperty("mysql.table.include"); 111 | String mysqlTableExclude = properties.getProperty("mysql.table.exclude"); 112 | String mysqlColumnExclude = properties.getProperty("mysql.column.exclude"); 113 | 114 | if (StringUtils.isNotBlank(mysqlTableInclude)) { 115 | for (String table : mysqlTableInclude.split(",")) { 116 | if (StringUtils.isNotBlank(table)) { 117 | Config.tableIncludeList.add(table); 118 | } 119 | } 120 | } 121 | 122 | if (StringUtils.isNotBlank(mysqlTableExclude)) { 123 | for (String table : mysqlTableExclude.split(",")) { 124 | if (StringUtils.isNotBlank(table)) { 125 | Config.tableExcludeList.add(table); 126 | } 127 | } 128 | } 129 | 130 | Config.columnExcludeList.add("_timestamp"); 131 | if (StringUtils.isNotBlank(mysqlColumnExclude)) { 132 | for (String table : mysqlColumnExclude.split(",")) { 133 | if (StringUtils.isNotBlank(table)) { 134 | Config.columnExcludeList.add(table); 135 | } 136 | } 137 | } 138 | } 139 | 140 | } 141 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/base/Field.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker.base; 2 | 3 | /** 4 | * 对应表中的字段 5 | */ 6 | public class Field { 7 | /** 8 | * 表的字段名称(原名) 9 | */ 10 | private String tname; 11 | /** 12 | * 字段名称(首字母小写) 13 | */ 14 | private String name; 15 | /** 16 | * 字段名称(首字大小写) 17 | */ 18 | private String bname; 19 | /** 20 | * 字段类型 21 | */ 22 | private String classType; 23 | /** 24 | * 字段描述 25 | */ 26 | private String desc; 27 | 28 | /** 29 | * EXTRA 30 | */ 31 | private String extra; 32 | 33 | /** 34 | * 字段最大长度 35 | */ 36 | private Integer maxRandomLen; 37 | 38 | public String getTname() { 39 | return tname; 40 | } 41 | 42 | public void setTname(String tname) { 43 | this.tname = tname; 44 | } 45 | 46 | public String getName() { 47 | return name; 48 | } 49 | 50 | public void setName(String name) { 51 | this.name = name; 52 | } 53 | 54 | public String getBname() { 55 | return bname; 56 | } 57 | 58 | public void setBname(String bname) { 59 | this.bname = bname; 60 | } 61 | 62 | public String getClassType() { 63 | return classType; 64 | } 65 | 66 | public void setClassType(String classType) { 67 | this.classType = classType; 68 | } 69 | 70 | public String getDesc() { 71 | return desc; 72 | } 73 | 74 | public void setDesc(String desc) { 75 | this.desc = desc; 76 | } 77 | 78 | public String getExtra() { 79 | return extra; 80 | } 81 | 82 | public void setExtra(String extra) { 83 | this.extra = extra; 84 | } 85 | 86 | public Integer getMaxRandomLen() { 87 | return maxRandomLen; 88 | } 89 | 90 | public void setMaxRandomLen(Integer maxRandomLen) { 91 | this.maxRandomLen = maxRandomLen; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/FreemarkerConfig.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker.freemarker; 2 | 3 | import com.flyer.maker.base.Config; 4 | import freemarker.template.Configuration; 5 | import freemarker.template.TemplateModelException; 6 | 7 | import java.io.IOException; 8 | import java.util.Locale; 9 | 10 | /** 11 | * freemarker配置初始化 12 | */ 13 | public class FreemarkerConfig { 14 | 15 | private static Configuration config; 16 | 17 | public static Configuration getConfiguration() throws IOException, TemplateModelException { 18 | if (config == null) { 19 | config = new Configuration(Configuration.VERSION_2_3_28); 20 | config.setClassForTemplateLoading(FreemarkerConfig.class, "templete"); 21 | config.setLocale(Locale.CHINA); 22 | config.setDefaultEncoding("UTF-8"); 23 | config.setSharedVariable("projectPackage", Config.projectPackage); 24 | config.setSharedVariable("author", Config.author); 25 | config.setSharedVariable("projectGroupId", Config.projectGroupId); 26 | config.setSharedVariable("projectArtifactId", Config.projectArtifactId); 27 | config.setSharedVariable("mysqlJdbcUrl", Config.mysqlJdbcUrl); 28 | config.setSharedVariable("mysqlUsername", Config.mysqlUsername); 29 | config.setSharedVariable("mysqlPassword", Config.mysqlPassword); 30 | } 31 | return config; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/ArithUtil.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.utils; 2 | 3 | import java.math.BigDecimal; 4 | 5 | /** 6 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 7 | */ 8 | public class ArithUtil { 9 | 10 | private static final int DEF_DIV_SCALE = 10; 11 | 12 | private ArithUtil() { 13 | } 14 | 15 | public static double add(double v1, double v2) { 16 | BigDecimal b1 = new BigDecimal(Double.toString(v1)); 17 | BigDecimal b2 = new BigDecimal(Double.toString(v2)); 18 | return b1.add(b2).doubleValue(); 19 | } 20 | 21 | public static double sub(double v1, double v2) { 22 | BigDecimal b1 = new BigDecimal(Double.toString(v1)); 23 | BigDecimal b2 = new BigDecimal(Double.toString(v2)); 24 | return b1.subtract(b2).setScale(2, BigDecimal.ROUND_DOWN).doubleValue(); 25 | } 26 | 27 | public static double mul(double v1, double v2) { 28 | BigDecimal b1 = new BigDecimal(Double.toString(v1)); 29 | BigDecimal b2 = new BigDecimal(Double.toString(v2)); 30 | return b1.multiply(b2).doubleValue(); 31 | } 32 | 33 | public static double div(double v1, double v2) { 34 | return div(v1, v2, DEF_DIV_SCALE); 35 | } 36 | 37 | public static double div(double v1, double v2, int scale) { 38 | if (scale < 0) { 39 | throw new IllegalArgumentException("The scale must be a positive integer or zero"); 40 | } 41 | BigDecimal b1 = new BigDecimal(Double.toString(v1)); 42 | BigDecimal b2 = new BigDecimal(Double.toString(v2)); 43 | return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); 44 | } 45 | 46 | public static double round(double v, int scale) { 47 | if (scale < 0) { 48 | throw new IllegalArgumentException("The scale must be a positive integer or zero"); 49 | } 50 | BigDecimal b = new BigDecimal(Double.toString(v)); 51 | BigDecimal one = new BigDecimal("1"); 52 | return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); 53 | } 54 | 55 | } 56 | 57 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/ArithUtilTest.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.utils; 2 | 3 | import org.junit.Test; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 11 | */ 12 | public class ArithUtilTest { 13 | 14 | private final static Logger log = LoggerFactory.getLogger(ArithUtilTest.class); 15 | 16 | @Test 17 | public void add() throws Exception { 18 | double d1 = 0.11d; 19 | double d2 = 0.1d; 20 | double res = ArithUtil.add(d1, d2); 21 | assertEquals(0.21d, res, 0); 22 | log.info("add res : {}", res); 23 | } 24 | 25 | @Test 26 | public void sub() throws Exception { 27 | double d1 = 0.11d; 28 | double d2 = 0.1d; 29 | double res = ArithUtil.sub(d1, d2); 30 | assertEquals(0.01d, res, 0); 31 | log.info("sub res : {}", res); 32 | } 33 | 34 | @Test 35 | public void mul() throws Exception { 36 | double d1 = 1.999999d; 37 | double d2 = 2.88888d; 38 | double res = ArithUtil.mul(d1, d2); 39 | log.info("mul res : {}", res); 40 | } 41 | 42 | @Test 43 | public void div() throws Exception { 44 | double d1 = 1.1; 45 | double d2 = 0.9; 46 | double res = ArithUtil.div(d1, d2); 47 | log.info("div res: {}", res); 48 | } 49 | 50 | @Test 51 | public void div1() throws Exception { 52 | double d1 = 1.1; 53 | double d2 = 0.9; 54 | double res = ArithUtil.div(d1, d2, 5); 55 | log.info("div1 res: {}", res); 56 | } 57 | 58 | @Test 59 | public void round() throws Exception { 60 | double d1 = 1.9999999999; 61 | double res = ArithUtil.round(d1, 5); 62 | log.info("round res: {}", res); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/BaseController.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.common; 2 | 3 | import ${projectPackage}.common.exception.BizException; 4 | import ${projectPackage}.constant.ErrorEnum; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.validation.BindingResult; 8 | import org.springframework.validation.ObjectError; 9 | 10 | import java.util.Iterator; 11 | 12 | /** 13 | * 14 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 15 | */ 16 | public class BaseController { 17 | 18 | protected Logger log = LoggerFactory.getLogger(getClass()); 19 | 20 | public void checkJSR303(BindingResult result) { 21 | if (result.hasErrors()) { 22 | StringBuilder sb = new StringBuilder(); 23 | Iterator iterator = result.getAllErrors().iterator(); 24 | while (iterator.hasNext()) { 25 | sb.append(iterator.next().getDefaultMessage()); 26 | if (iterator.hasNext()) { 27 | sb.append(","); 28 | } 29 | } 30 | log.warn("checkJSR303 fail, error: {}", sb.toString()); 31 | BizException.throwOut(ErrorEnum.PARAMETER_ILLEGAL); 32 | } 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/BaseResponse.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.common; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Base rest response 7 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 8 | */ 9 | public class BaseResponse implements Serializable { 10 | 11 | private static final long serialVersionUID = -9143234037177972208L; 12 | 13 | public static final int CODE_SUCCESS = 0; 14 | public static final int CODE_FAIL = -1; 15 | public static final String MSG_SUCCESS = "success"; 16 | public static final String MSG_FAIL = "fail"; 17 | 18 | private int code; 19 | 20 | private String message; 21 | 22 | private T data; 23 | 24 | public int getCode() { 25 | return code; 26 | } 27 | 28 | public void setCode(int code) { 29 | this.code = code; 30 | } 31 | 32 | public String getMessage() { 33 | return message; 34 | } 35 | 36 | public void setMessage(String message) { 37 | this.message = message; 38 | } 39 | 40 | public T getData() { 41 | return data; 42 | } 43 | 44 | public void setData(T data) { 45 | this.data = data; 46 | } 47 | 48 | private BaseResponse(Builder builder) { 49 | this.code = builder.code; 50 | this.message = builder.message; 51 | this.data = builder.data; 52 | } 53 | 54 | public static Builder ok() { 55 | return new Builder().code(CODE_SUCCESS).message(MSG_SUCCESS); 56 | } 57 | 58 | public static Builder ok(T t) { 59 | return new Builder().code(CODE_SUCCESS).message(MSG_SUCCESS).data(t); 60 | } 61 | 62 | public static Builder error() { 63 | return new Builder().code(CODE_FAIL).message(MSG_FAIL); 64 | } 65 | 66 | 67 | public static class Builder { 68 | 69 | private int code; 70 | private String message; 71 | private T data; 72 | 73 | public Builder code(int code) { 74 | this.code = code; 75 | return this; 76 | } 77 | 78 | public Builder message(String message) { 79 | this.message = message; 80 | return this; 81 | } 82 | 83 | public Builder data(T data) { 84 | this.data = data; 85 | return this; 86 | } 87 | 88 | public Builder success() { 89 | this.code = CODE_SUCCESS; 90 | this.message = MSG_SUCCESS; 91 | return this; 92 | } 93 | 94 | public Builder fail() { 95 | this.code = CODE_FAIL; 96 | this.message = MSG_FAIL; 97 | return this; 98 | } 99 | 100 | public BaseResponse build() { 101 | return new BaseResponse(this); 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/BeanFactoryRegister.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.common; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.beans.factory.BeanFactory; 5 | import org.springframework.beans.factory.BeanFactoryAware; 6 | import org.springframework.stereotype.Component; 7 | 8 | /** 9 | * Spring context tools 10 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 11 | */ 12 | @Component 13 | public class BeanFactoryRegister implements BeanFactoryAware { 14 | 15 | public static BeanFactory beanFactory; 16 | 17 | @Override 18 | public void setBeanFactory(BeanFactory beanFactory) throws BeansException { 19 | BeanFactoryRegister.beanFactory = beanFactory; 20 | } 21 | 22 | public static Object getBean(String name) { 23 | return beanFactory.getBean(name); 24 | } 25 | 26 | public static T getBean(Class clazz) { 27 | return beanFactory.getBean(clazz); 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/BeanFactoryRegisterTest.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.common; 2 | 3 | import ${projectPackage}.AbstractTest; 4 | import org.junit.Test; 5 | import org.springframework.core.env.Environment; 6 | 7 | import java.util.Arrays; 8 | 9 | import static org.junit.Assert.assertNotNull; 10 | 11 | /** 12 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 13 | */ 14 | public class BeanFactoryRegisterTest extends AbstractTest { 15 | 16 | @Test 17 | public void getBean() throws Exception { 18 | Environment environment = (Environment) BeanFactoryRegister.getBean("environment"); 19 | log.warn("curernt active env: {}", Arrays.toString(environment.getActiveProfiles())); 20 | assertNotNull("getBean object is null", environment); 21 | } 22 | 23 | @Test 24 | public void getBean1() throws Exception { 25 | Environment environment = BeanFactoryRegister.getBean(Environment.class); 26 | log.warn("curernt default env: {}", Arrays.toString(environment.getDefaultProfiles())); 27 | assertNotNull("getBean1 object is null", environment); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/BizException.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.common.exception; 2 | 3 | import ${projectPackage}.constant.ErrorEnum; 4 | 5 | /** 6 | * User-defined Exception 7 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 8 | */ 9 | public class BizException extends RuntimeException { 10 | 11 | /** 12 | * error info 13 | */ 14 | private ErrorEnum error; 15 | 16 | public BizException(ErrorEnum error) { 17 | this.error = error; 18 | } 19 | 20 | public ErrorEnum getError() { 21 | return error; 22 | } 23 | 24 | public static void throwOut(ErrorEnum error) { 25 | throw new BizException(error); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/CommonController.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.web; 2 | 3 | import ch.qos.logback.classic.Level; 4 | import ch.qos.logback.classic.LoggerContext; 5 | import ${projectPackage}.common.BaseController; 6 | import ${projectPackage}.common.BaseResponse; 7 | import ${projectPackage}.common.exception.BizException; 8 | import ${projectPackage}.constant.ErrorEnum; 9 | import org.apache.commons.lang3.StringUtils; 10 | import org.slf4j.LoggerFactory; 11 | import org.springframework.web.bind.annotation.GetMapping; 12 | import org.springframework.web.bind.annotation.PathVariable; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | import java.util.ArrayList; 16 | import java.util.HashMap; 17 | import java.util.List; 18 | import java.util.Map; 19 | 20 | /** 21 | * Common Controller 22 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 23 | */ 24 | @RestController 25 | public class CommonController extends BaseController { 26 | 27 | /** 28 | * healthCheck 29 | * 30 | * @return 31 | */ 32 | @GetMapping(value = "healthCheck") 33 | public BaseResponse healthCheck() { 34 | return BaseResponse.ok().build(); 35 | } 36 | 37 | /** 38 | * set logger's level 39 | * 40 | * @param logger 41 | * @param level 42 | * @return 43 | */ 44 | @GetMapping(value = "setLevel") 45 | public BaseResponse setLoggerLevel(String logger, String level) { 46 | if (StringUtils.isBlank(logger) || StringUtils.isBlank(level)) { 47 | BizException.throwOut(ErrorEnum.PARAMETER_ILLEGAL); 48 | } 49 | LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); 50 | loggerContext.getLogger(logger).setLevel(Level.valueOf(level)); 51 | log.info("logger: {} was set to : {}", logger, level); 52 | return BaseResponse.ok().build(); 53 | } 54 | 55 | /** 56 | * view the current level of logger 57 | *

58 | * usage: 59 | * 1. /loggers for all logger 60 | * 2. /loggers/${projectPackage}.CommonController for specified logger 61 | * 62 | * @param name 63 | * @return 64 | */ 65 | @GetMapping(value = {"loggers/{name:.+}", "loggers"}) 66 | public BaseResponse loggers(@PathVariable(required = false) String name) { 67 | List loggerList = new ArrayList<>(); 68 | List list = new ArrayList(); 69 | LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); 70 | if (StringUtils.isNotBlank(name)) { 71 | loggerList.add(loggerContext.getLogger(name)); 72 | } else { 73 | loggerList = loggerContext.getLoggerList(); 74 | } 75 | for (ch.qos.logback.classic.Logger logger : loggerList) { 76 | //filter user's logger 77 | if (!logger.getName().startsWith("${projectPackage}")) { 78 | continue; 79 | } 80 | list.add(new HashMap() {{ 81 | put("logger", logger.getName()); 82 | put("level", logger.getEffectiveLevel().levelStr); 83 | }}); 84 | } 85 | return BaseResponse.ok(list).build(); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/CommonControllerTest.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.web; 2 | 3 | import ${projectPackage}.AbstractMVCTest; 4 | import ${projectPackage}.common.BaseResponse; 5 | import org.junit.Test; 6 | import org.springframework.http.MediaType; 7 | 8 | import static org.junit.Assert.*; 9 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 10 | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; 11 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; 12 | 13 | /** 14 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 15 | */ 16 | public class CommonControllerTest extends AbstractMVCTest { 17 | 18 | @Test 19 | public void healthCheck() throws Exception { 20 | this.mockMvc.perform(get("/healthCheck")).andExpect(status().isOk()).andDo(print()) 21 | .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) 22 | .andExpect(jsonPath("code").value(BaseResponse.CODE_SUCCESS)); 23 | } 24 | 25 | @Test 26 | public void setLoggerLevel() throws Exception { 27 | this.mockMvc.perform(get("/setLevel").param("logger", "${projectPackage}").param("level", "DEBUG")) 28 | .andExpect(status().isOk()).andDo(print()) 29 | .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) 30 | .andExpect(jsonPath("code").value(BaseResponse.CODE_SUCCESS)); 31 | } 32 | 33 | @Test 34 | public void loggers() throws Exception { 35 | this.mockMvc.perform(get("/loggers")) 36 | .andExpect(status().isOk()).andDo(print()) 37 | .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) 38 | .andExpect(jsonPath("code").value(BaseResponse.CODE_SUCCESS)); 39 | 40 | this.mockMvc.perform(get("/loggers/${projectPackage}")) 41 | .andExpect(status().isOk()).andDo(print()) 42 | .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) 43 | .andExpect(jsonPath("code").value(BaseResponse.CODE_SUCCESS)); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/ControllerInterceptor.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.common.interceptor; 2 | 3 | import org.apache.commons.io.IOUtils; 4 | import org.apache.commons.lang3.StringUtils; 5 | import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * 14 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 15 | */ 16 | public class ControllerInterceptor extends HandlerInterceptorAdapter { 17 | 18 | @Override 19 | public boolean preHandle(HttpServletRequest httpServletRequest, 20 | HttpServletResponse httpServletResponse, Object o) throws Exception { 21 | long begin = System.currentTimeMillis(); 22 | HttpLog httpLog = new HttpLog(); 23 | httpLog.setGeneral(buildGeneral(httpServletRequest, begin)); 24 | httpLog.setParameters(buildParameter(httpServletRequest)); 25 | httpLog.setRequestBody(IOUtils.toString(httpServletRequest.getInputStream(), "utf-8")); 26 | HttpLogHolder.set(httpLog); 27 | return true; 28 | } 29 | 30 | private Map buildGeneral(HttpServletRequest request, long begin) { 31 | Map map = new HashMap(); 32 | map.put("URI", request.getRequestURI()); 33 | map.put("method", request.getMethod()); 34 | map.put("queryString", request.getQueryString() == null ? "" : request.getQueryString()); 35 | map.put("requestTime", begin); 36 | return map; 37 | } 38 | 39 | private Map buildParameter(HttpServletRequest request) { 40 | Map map = request.getParameterMap(); 41 | Map resultMap = new HashMap(); 42 | for (Map.Entry entry : map.entrySet()) { 43 | resultMap.put(entry.getKey(), StringUtils.join(entry.getValue(), ",")); 44 | } 45 | return resultMap; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/DBUtils.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}; 2 | 3 | import ${projectPackage}.common.BeanFactoryRegister; 4 | import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import javax.sql.DataSource; 9 | import java.sql.Connection; 10 | import java.sql.SQLException; 11 | import java.sql.Statement; 12 | 13 | /** 14 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 15 | */ 16 | public class DBUtils { 17 | 18 | protected final static Logger log = LoggerFactory.getLogger(DBUtils.class); 19 | 20 | private final static String TRUNCATE_TABLE_SQL_PATTERN = "TRUNCATE %s"; 21 | 22 | /** 23 | * 由于每次执行完UT,都会清空库,所以需要 24 | * 检查当前配置的jdbc.url,连接的数据库是否以'_ut'结尾 25 | * 如果不是,则单元测试中断。 26 | * 该策略的目的是:保证单元测试每次执行幂等 27 | */ 28 | public static void checkDBName() { 29 | DataSource dataSource = null; 30 | Connection connection = null; 31 | try { 32 | DefaultSqlSessionFactory sqlSession = 33 | (DefaultSqlSessionFactory) BeanFactoryRegister.getBean("sqlSessionFactory"); 34 | dataSource = sqlSession.getConfiguration().getEnvironment().getDataSource(); 35 | connection = dataSource.getConnection(); 36 | String db = connection.getCatalog(); 37 | if (!db.endsWith("_ut")) { 38 | log.error("单元测试数据库名称必须以{ _ut }结尾,当前库: {}", db); 39 | log.error("单元测试退出"); 40 | System.exit(100); 41 | } 42 | log.info("unit test currnt db: {}", db); 43 | } catch (Exception e) { 44 | log.error("checkDBName error", e); 45 | } finally { 46 | try { 47 | connection.close(); 48 | } catch (SQLException e) { 49 | log.error("db close error", e); 50 | } 51 | } 52 | } 53 | 54 | /** 55 | * truncate table by table name 56 | * 57 | * @param tableName 58 | */ 59 | public static void truncateTable(String tableName) { 60 | DataSource dataSource = null; 61 | Connection connection = null; 62 | Statement statement = null; 63 | String sql = String.format(TRUNCATE_TABLE_SQL_PATTERN, tableName); 64 | try { 65 | DefaultSqlSessionFactory sqlSession = 66 | (DefaultSqlSessionFactory) BeanFactoryRegister.getBean("sqlSessionFactory"); 67 | dataSource = sqlSession.getConfiguration().getEnvironment().getDataSource(); 68 | connection = dataSource.getConnection(); 69 | statement = connection.createStatement(); 70 | statement.execute(sql); 71 | log.info("truncateTable {} complete", tableName); 72 | } catch (Exception e) { 73 | log.error("truncateTable error, table: {}", tableName, e); 74 | } finally { 75 | try { 76 | statement.close(); 77 | connection.close(); 78 | } catch (SQLException e) { 79 | log.error("db close error", e); 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/DateUtil.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.utils; 2 | 3 | import org.joda.time.DateTime; 4 | import org.joda.time.LocalTime; 5 | import org.joda.time.format.DateTimeFormat; 6 | import org.joda.time.format.DateTimeFormatter; 7 | 8 | import java.sql.Timestamp; 9 | import java.text.DateFormat; 10 | import java.text.ParseException; 11 | import java.text.SimpleDateFormat; 12 | import java.util.Calendar; 13 | import java.util.Date; 14 | 15 | /** 16 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 17 | */ 18 | public class DateUtil { 19 | 20 | public static final String FORMAT_DATE = "yyyy-MM-dd"; 21 | public static final String FORMAT_DATETIME = "yyyy-MM-dd HH:mm"; 22 | public static final String FORMAT_TIME = "HH:mm"; 23 | public static final String YYYY = "yyyy"; 24 | public static final String MM = "MM"; 25 | public static final String DD = "dd"; 26 | 27 | private DateUtil() { 28 | } 29 | 30 | /** 31 | * 字符串转为日期 32 | * 33 | * @param input 34 | * @param pattern the date format patterns to use 35 | * @return 36 | */ 37 | public static Date parse(String input, String pattern) { 38 | DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern); 39 | DateTime dateTime = fmt.parseDateTime(input); 40 | return dateTime.toDate(); 41 | } 42 | 43 | /** 44 | * 日期转为字符串 45 | * 46 | * @param date 47 | * @param pattern 48 | * @return 49 | */ 50 | public static String format(Date date, String pattern) { 51 | DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern); 52 | return fmt.print(new DateTime(date)); 53 | } 54 | 55 | /** 56 | * 字符串转为joda日期 57 | * 58 | * @param input 59 | * @param pattern 60 | * @return 61 | */ 62 | public static DateTime parseDateTime(String input, String pattern) { 63 | DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern); 64 | DateTime dateTime = fmt.parseDateTime(input); 65 | return dateTime; 66 | } 67 | 68 | /** 69 | * joda日期转为字符串 70 | * 71 | * @param dateTime 72 | * @param pattern 73 | * @return 74 | */ 75 | public static String format(DateTime dateTime, String pattern) { 76 | DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern); 77 | return fmt.print(dateTime); 78 | } 79 | 80 | 81 | /** 82 | * 时间字符串转为时间 83 | * 84 | * @param time 85 | * @param pattern 86 | * @return 87 | */ 88 | public static LocalTime parseTime(String time, String pattern) { 89 | DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern); 90 | return fmt.parseLocalTime(time); 91 | } 92 | 93 | 94 | /** 95 | * getWeek:(根据时间计算星期几,结果为阿拉伯数字).
96 | * 例如: 97 | * 输入:“2015.4.28” 98 | * 输出:“2” 99 | * 100 | * @param date 101 | * @return 102 | */ 103 | public static String getWeekArabic(Date date) { 104 | Calendar c = Calendar.getInstance(); 105 | c.setTime(date); 106 | int dayForWeek = 0; 107 | if (c.get(Calendar.DAY_OF_WEEK) == 1) { 108 | dayForWeek = 7; 109 | } else { 110 | dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1; 111 | } 112 | return String.valueOf(dayForWeek); 113 | } 114 | 115 | /** 116 | * getWeek:(根据时间计算星期几,结果为文字描述).
117 | * 例如: 118 | * 输入:“2015.4.28” 119 | * 输出:“星期二” 120 | * 121 | * @param date 122 | * @return 123 | */ 124 | public static String getWeek(Date date) { 125 | return new SimpleDateFormat("EEEE").format(date); 126 | } 127 | 128 | /** 129 | * 获取指定时间向前或向后多少秒后的时间 负数为向前,正数为向后 130 | * 131 | * @param date 132 | * @param second 133 | * @return 134 | */ 135 | public static Date getNextSecond(Date date, int second) { 136 | Calendar calendar = Calendar.getInstance(); 137 | calendar.setTime(date); 138 | calendar.add(Calendar.SECOND, second); 139 | date = calendar.getTime(); 140 | return date; 141 | } 142 | 143 | /** 144 | * 时间对象转换成字符串 145 | * 146 | * @param date 147 | * @param formatStr 148 | * @return 149 | */ 150 | public static String date2string(Date date, String formatStr) { 151 | String strDate = ""; 152 | if (date != null) { 153 | SimpleDateFormat sdf = new SimpleDateFormat(formatStr); 154 | strDate = sdf.format(date); 155 | } 156 | return strDate; 157 | } 158 | 159 | public static Date date2date(Date date, String formatStr) { 160 | SimpleDateFormat sdf = new SimpleDateFormat(formatStr); 161 | String str = sdf.format(date); 162 | try { 163 | date = sdf.parse(str); 164 | } catch (ParseException e) { 165 | throw new RuntimeException(e); 166 | } 167 | return date; 168 | } 169 | 170 | /** 171 | * sql时间对象转换成字符串 172 | * 173 | * @param timestamp 174 | * @param formatStr 175 | * @return 176 | */ 177 | public static String timestamp2string(Timestamp timestamp, String formatStr) { 178 | SimpleDateFormat sdf = new SimpleDateFormat(formatStr); 179 | return sdf.format(timestamp); 180 | } 181 | 182 | /** 183 | * 字符串转换成时间对象 184 | * 185 | * @param dateString 186 | * @param formatStr 187 | * @return 188 | */ 189 | public static Date string2date(String dateString, String formatStr) { 190 | Date formateDate = null; 191 | DateFormat format = new SimpleDateFormat(formatStr); 192 | try { 193 | formateDate = format.parse(dateString); 194 | } catch (ParseException e) { 195 | throw new RuntimeException(e); 196 | } 197 | return formateDate; 198 | } 199 | 200 | /** 201 | * Date类型转换为Timestamp类型 202 | * 203 | * @param date 204 | * @return 205 | */ 206 | public static Timestamp date2timestamp(Date date) { 207 | if (date == null) { 208 | return null; 209 | } 210 | return new Timestamp(date.getTime()); 211 | } 212 | 213 | /** 214 | * 获得当前年份 215 | * 216 | * @return 217 | */ 218 | public static String getNowYear() { 219 | SimpleDateFormat sdf = new SimpleDateFormat(YYYY); 220 | return sdf.format(new Date()); 221 | } 222 | 223 | /** 224 | * 获得当前月份 225 | * 226 | * @return 227 | */ 228 | public static String getNowMonth() { 229 | SimpleDateFormat sdf = new SimpleDateFormat(MM); 230 | return sdf.format(new Date()); 231 | } 232 | 233 | /** 234 | * 获得当前日期中的日 235 | * 236 | * @return 237 | */ 238 | public static String getNowDay() { 239 | SimpleDateFormat sdf = new SimpleDateFormat(DD); 240 | return sdf.format(new Date()); 241 | } 242 | 243 | /** 244 | * 获取指定时间向前或向后多少小时后的时间 负数为向前,正数为向后 245 | * 246 | * @param date 247 | * @param hour 248 | * @return 249 | */ 250 | public static Date getNextHour(Date date, int hour) { 251 | Calendar calendar = Calendar.getInstance(); 252 | calendar.setTime(date); 253 | calendar.add(Calendar.HOUR_OF_DAY, hour); 254 | date = calendar.getTime(); 255 | return date; 256 | } 257 | 258 | /** 259 | * 获取指定时间向前或向后多少月后的时间 负数为向前,正数为向后 260 | * 261 | * @param date 262 | * @param month 263 | * @return 264 | */ 265 | public static Date getNextMonth(Date date, int month) { 266 | Calendar calendar = Calendar.getInstance(); 267 | calendar.setTime(date); 268 | calendar.add(Calendar.MONTH, month); 269 | date = calendar.getTime(); 270 | return date; 271 | } 272 | } 273 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/ErrorEnum.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.constant; 2 | 3 | /** 4 | * Errors 5 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 6 | */ 7 | public enum ErrorEnum { 8 | //4XX 9 | PARAMETER_ILLEGAL(400, "参数不合法"), 10 | NOT_FOUND(404, "资源未找到"), 11 | RESOURCE_CONFLICT(409, "资源已存在"), 12 | 13 | //5XX 14 | INTERNAL_SERVER_ERROR(500, "内部错误"), 15 | INTERNAL_SYSTEM_TIMEOUT(502, "内部系统调用超时"), 16 | DB_FAIL(516, "查询/操作数据库失败"), 17 | DB_ERROR(517, "查询/操作数据库错误"), 18 | ; 19 | 20 | public final int code; 21 | public final String message; 22 | 23 | ErrorEnum(int code, String message) { 24 | this.code = code; 25 | this.message = message; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/GlobalExceptionHandler.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.common.exception; 2 | 3 | import ${projectPackage}.common.BaseResponse; 4 | import ${projectPackage}.constant.ErrorEnum; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.web.bind.annotation.ControllerAdvice; 8 | import org.springframework.web.bind.annotation.ExceptionHandler; 9 | import org.springframework.web.bind.annotation.ResponseBody; 10 | 11 | import javax.servlet.http.HttpServletRequest; 12 | 13 | /** 14 | * global exception handler for controller 15 | *

16 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 17 | */ 18 | @ControllerAdvice 19 | public class GlobalExceptionHandler { 20 | 21 | private final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); 22 | 23 | /** 24 | * Biz exception handler 25 | * 26 | * @param req 27 | * @param e 28 | * @return 29 | */ 30 | @ExceptionHandler(value = BizException.class) 31 | @ResponseBody 32 | public BaseResponse businessErrorHandler(HttpServletRequest req, BizException e) { 33 | ErrorEnum error = e.getError(); 34 | if (error == null) { 35 | log.error("businessErrorHandler error, URI: {}", req.getRequestURI(), e); 36 | return BaseResponse.error().build(); 37 | } else { 38 | //no need to print the stack exception log again 39 | log.error("businessErrorHandler error, URI: {}, code : {}, message : {}", 40 | req.getRequestURI(), error.code, error.message); 41 | return new BaseResponse.Builder<>().code(error.code).message(error.message).build(); 42 | } 43 | } 44 | 45 | /** 46 | * system exception handler 47 | * 48 | * @param req 49 | * @param e 50 | * @return 51 | */ 52 | @ExceptionHandler(value = Exception.class) 53 | @ResponseBody 54 | public BaseResponse systemErrorHandler(HttpServletRequest req, Exception e) { 55 | log.error("systemErrorHandler error, URI: {}", req.getRequestURI(), e); 56 | return BaseResponse.error().build(); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/HttpLog.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.common.interceptor; 2 | 3 | import ${projectPackage}.common.BaseResponse; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 9 | */ 10 | public class HttpLog { 11 | 12 | private Map general; 13 | 14 | private Map parameters; 15 | 16 | private String requestBody; 17 | 18 | private BaseResponse responseBody; 19 | 20 | public Map getParameters() { 21 | return parameters; 22 | } 23 | 24 | public void setParameters(Map parameters) { 25 | this.parameters = parameters; 26 | } 27 | 28 | public Map getGeneral() { 29 | return general; 30 | } 31 | 32 | public void setGeneral(Map general) { 33 | this.general = general; 34 | } 35 | 36 | public String getRequestBody() { 37 | return requestBody; 38 | } 39 | 40 | public void setRequestBody(String requestBody) { 41 | this.requestBody = requestBody; 42 | } 43 | 44 | public BaseResponse getResponseBody() { 45 | return responseBody; 46 | } 47 | 48 | public void setResponseBody(BaseResponse responseBody) { 49 | this.responseBody = responseBody; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/HttpLogHolder.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.common.interceptor; 2 | 3 | import org.springframework.core.NamedThreadLocal; 4 | 5 | /** 6 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 7 | */ 8 | public class HttpLogHolder { 9 | private static NamedThreadLocal threadLocal = 10 | new NamedThreadLocal<>("HttpLogHolder"); 11 | 12 | public static void set(HttpLog httpLog) { 13 | threadLocal.set(httpLog); 14 | } 15 | 16 | public static HttpLog get() { 17 | return threadLocal.get(); 18 | } 19 | 20 | public static void clean() { 21 | threadLocal.remove(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/LogResponseBodyAdvice.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.common.interceptor; 2 | 3 | import ${projectPackage}.common.BaseResponse; 4 | import com.vip.vjtools.vjkit.mapper.JsonMapper; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.core.MethodParameter; 8 | import org.springframework.http.MediaType; 9 | import org.springframework.http.server.ServerHttpRequest; 10 | import org.springframework.http.server.ServerHttpResponse; 11 | import org.springframework.web.bind.annotation.ControllerAdvice; 12 | import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; 13 | 14 | /** 15 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 16 | */ 17 | @ControllerAdvice 18 | public class LogResponseBodyAdvice implements ResponseBodyAdvice { 19 | 20 | private Logger log = LoggerFactory.getLogger(getClass()); 21 | 22 | @Override 23 | public boolean supports(MethodParameter returnType, Class converterType) { 24 | return true; 25 | } 26 | 27 | @Override 28 | public BaseResponse beforeBodyWrite(BaseResponse body, MethodParameter returnType, 29 | MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, 30 | ServerHttpResponse response) { 31 | try { 32 | long end = System.currentTimeMillis(); 33 | HttpLog httpLog = HttpLogHolder.get(); 34 | if (httpLog != null) { 35 | httpLog.getGeneral() 36 | .put("latency", end - (long) httpLog.getGeneral().get("requestTime")); 37 | httpLog.setResponseBody(body); 38 | log.info(JsonMapper.INSTANCE.toJson(httpLog)); 39 | } else { 40 | log.warn("HttpLogHolder error"); 41 | } 42 | return body; 43 | } finally { 44 | HttpLogHolder.clean(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/LogbackProfileListener.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.common.listener; 2 | 3 | import ch.qos.logback.ext.spring.web.LogbackConfigListener; 4 | import ch.qos.logback.ext.spring.web.WebLogbackConfigurer; 5 | import org.apache.commons.lang3.StringUtils; 6 | import uk.org.lidalia.sysoutslf4j.context.SysOutOverSLF4J; 7 | 8 | import javax.servlet.ServletContextEvent; 9 | 10 | /** 11 | * logback config listener 12 | * solve multiple spring profiles problems 13 | *

14 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 15 | */ 16 | public class LogbackProfileListener extends LogbackConfigListener { 17 | 18 | private static final String DEFAULT_PROFILE = "dev"; 19 | private static final String LOGBACK_CONFIG_FILE_PATTERN = "classpath:%s/logback.xml"; 20 | 21 | @Override 22 | public void contextInitialized(ServletContextEvent event) { 23 | String springProfile = System.getProperty("spring.profiles.active"); 24 | //use 'dev' default 25 | if (StringUtils.isEmpty(springProfile)) { 26 | springProfile = DEFAULT_PROFILE; 27 | } 28 | String logConfigPath = String.format(LOGBACK_CONFIG_FILE_PATTERN, springProfile); 29 | //only supported servlet 3+ 30 | event.getServletContext() 31 | .setInitParameter(WebLogbackConfigurer.CONFIG_LOCATION_PARAM, logConfigPath); 32 | 33 | super.contextInitialized(event); 34 | 35 | //console -> slf4j 36 | SysOutOverSLF4J.sendSystemOutAndErrToSLF4J(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/db/controllerTemplate.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.web; 2 | 3 | import ${projectPackage}.common.BaseController; 4 | import ${projectPackage}.common.BaseResponse; 5 | import ${projectPackage}.common.exception.BizException; 6 | import ${projectPackage}.constant.ErrorEnum; 7 | import ${projectPackage}.domain.${clazz.bclassName}; 8 | import ${projectPackage}.service.${clazz.bclassName}Service; 9 | import ${projectPackage}.web.req.SaveOrUpdate${clazz.bclassName}; 10 | import com.vip.vjtools.vjkit.collection.MapUtil; 11 | import jodd.bean.BeanCopy; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.validation.BindingResult; 14 | import org.springframework.web.bind.annotation.*; 15 | 16 | import javax.validation.Valid; 17 | 18 | /** 19 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 20 | */ 21 | @RestController 22 | @RequestMapping("${clazz.resouceName}") 23 | public class ${clazz.bclassName}Controller extends BaseController { 24 | 25 | @Autowired 26 | private ${clazz.bclassName}Service ${clazz.className}Service; 27 | 28 | @PostMapping(value = "add") 29 | public BaseResponse add${clazz.bclassName}(@RequestBody @Valid SaveOrUpdate${clazz.bclassName} saveOrUpdate${clazz.bclassName}Req, 30 | BindingResult result) { 31 | checkJSR303(result); 32 | ${clazz.bclassName} ${clazz.className} = new ${clazz.bclassName}(); 33 | BeanCopy.beans(saveOrUpdate${clazz.bclassName}Req, ${clazz.className}).copy(); 34 | ${clazz.className} = ${clazz.className}Service.save${clazz.bclassName}(${clazz.className}); 35 | return BaseResponse.ok(MapUtil.newHashMap("id", ${clazz.className}.getId())).build(); 36 | } 37 | 38 | @GetMapping(value = "remove") 39 | public BaseResponse remove${clazz.bclassName}(${clazz.idType} id) { 40 | if (id == null) { 41 | BizException.throwOut(ErrorEnum.PARAMETER_ILLEGAL); 42 | } 43 | ${clazz.className}Service.remove${clazz.bclassName}(id); 44 | return BaseResponse.ok(MapUtil.newHashMap("id", id)).build(); 45 | } 46 | 47 | @PostMapping(value = "edit") 48 | public BaseResponse edit${clazz.bclassName}(@RequestBody @Valid SaveOrUpdate${clazz.bclassName} saveOrUpdate${clazz.bclassName}Req, 49 | BindingResult result) { 50 | checkJSR303(result); 51 | ${clazz.bclassName} ${clazz.className} = new ${clazz.bclassName}(); 52 | BeanCopy.beans(saveOrUpdate${clazz.bclassName}Req, ${clazz.className}).copy(); 53 | ${clazz.className}Service.update${clazz.bclassName}(${clazz.className}); 54 | return BaseResponse.ok(MapUtil.newHashMap("id", ${clazz.className}.getId())).build(); 55 | } 56 | 57 | @GetMapping(value = "get") 58 | public BaseResponse get${clazz.bclassName}(${clazz.idType} id) { 59 | ${clazz.bclassName} ${clazz.className} = ${clazz.className}Service.find${clazz.bclassName}ById(id); 60 | return BaseResponse.ok(${clazz.className}).build(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/db/controllerTestTemplate.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.web; 2 | 3 | import ${projectPackage}.AbstractMVCTest; 4 | import ${projectPackage}.common.BaseResponse; 5 | import ${projectPackage}.data.${clazz.bclassName}Data; 6 | import ${projectPackage}.domain.${clazz.bclassName}; 7 | import ${projectPackage}.service.${clazz.bclassName}Service; 8 | import com.vip.vjtools.vjkit.mapper.JsonMapper; 9 | import org.junit.Test; 10 | import org.mockito.InjectMocks; 11 | import org.mockito.Mock; 12 | import org.springframework.http.MediaType; 13 | 14 | import javax.inject.Inject; 15 | 16 | import static org.mockito.Matchers.any; 17 | import static org.mockito.Matchers.anyInt; 18 | import static org.mockito.Matchers.anyLong; 19 | import static org.mockito.Mockito.when; 20 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 21 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 22 | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; 23 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; 24 | 25 | /** 26 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 27 | */ 28 | public class ${clazz.bclassName}ControllerTest extends AbstractMVCTest { 29 | 30 | @Mock 31 | private ${clazz.bclassName}Service ${clazz.className}Service; 32 | 33 | @Inject 34 | @InjectMocks 35 | private ${clazz.bclassName}Controller ${clazz.className}Controller; 36 | 37 | @Test 38 | public void add${clazz.bclassName}() throws Exception { 39 | 40 | ${clazz.bclassName} post${clazz.bclassName} = ${clazz.bclassName}Data.generatOne(false); 41 | 42 | when(${clazz.className}Service.save${clazz.bclassName}(any(${clazz.bclassName}.class))).thenReturn(${clazz.bclassName}Data.generatOne(true)); 43 | 44 | this.mockMvc.perform(post("/${clazz.className}/add").contentType(MediaType.APPLICATION_JSON_UTF8) 45 | .content(JsonMapper.INSTANCE.toJson(post${clazz.bclassName}))).andExpect(status().isOk()) 46 | .andDo(print()).andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) 47 | .andExpect(jsonPath("code").value(BaseResponse.CODE_SUCCESS)); 48 | } 49 | 50 | @Test 51 | public void get${clazz.bclassName}() throws Exception { 52 | 53 | when(${clazz.className}Service.find${clazz.bclassName}ById(any${clazz.idTypeSimple}())).thenReturn(${clazz.bclassName}Data.generatOne(true)); 54 | 55 | this.mockMvc.perform(get("/${clazz.className}/get").param("id", "1")).andExpect(status().isOk()) 56 | .andDo(print()).andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) 57 | .andExpect(jsonPath("code").value(BaseResponse.CODE_SUCCESS)); 58 | } 59 | 60 | @Test 61 | public void edit${clazz.bclassName}() throws Exception { 62 | ${clazz.bclassName} edit${clazz.bclassName} = ${clazz.bclassName}Data.generatOne(true); 63 | 64 | when(${clazz.className}Service.update${clazz.bclassName}(any(${clazz.bclassName}.class))).thenReturn(1); 65 | 66 | this.mockMvc.perform(post("/${clazz.className}/edit").contentType(MediaType.APPLICATION_JSON_UTF8) 67 | .content(JsonMapper.INSTANCE.toJson(edit${clazz.bclassName}))).andExpect(status().isOk()) 68 | .andDo(print()).andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) 69 | .andExpect(jsonPath("code").value(BaseResponse.CODE_SUCCESS)); 70 | } 71 | 72 | @Test 73 | public void remove${clazz.bclassName}() throws Exception { 74 | ${clazz.bclassName} remove${clazz.bclassName} = ${clazz.bclassName}Data.generatOne(true); 75 | 76 | when(${clazz.className}Service.remove${clazz.bclassName}(remove${clazz.bclassName}.getId())).thenReturn(1); 77 | 78 | this.mockMvc.perform(get("/${clazz.className}/remove").param("id", String.valueOf(remove${clazz.bclassName}.getId()))) 79 | .andExpect(status().isOk()).andDo(print()) 80 | .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) 81 | .andExpect(jsonPath("code").value(BaseResponse.CODE_SUCCESS)); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/db/daoTemplate.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.dao; 2 | 3 | import ${projectPackage}.domain.${clazz.bclassName}; 4 | import org.springframework.stereotype.Repository; 5 | 6 | /** 7 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 8 | */ 9 | @Repository 10 | public interface ${clazz.bclassName}Dao { 11 | 12 | Integer save${clazz.bclassName}(${clazz.bclassName} ${clazz.className}); 13 | 14 | Integer remove${clazz.bclassName}(${clazz.idType} id); 15 | 16 | Integer update${clazz.bclassName}(${clazz.bclassName} ${clazz.className}); 17 | 18 | ${clazz.bclassName} find${clazz.bclassName}ById(${clazz.idType} id); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/db/daoTestTemplate.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.dao; 2 | 3 | import ${projectPackage}.AbstractTest; 4 | import ${projectPackage}.DBUtils; 5 | import ${projectPackage}.data.${clazz.bclassName}Data; 6 | import ${projectPackage}.domain.${clazz.bclassName}; 7 | import com.vip.vjtools.vjkit.mapper.JsonMapper; 8 | import org.junit.AfterClass; 9 | import org.junit.Test; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | /** 15 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 16 | */ 17 | public class ${clazz.bclassName}DaoTest extends AbstractTest { 18 | 19 | @Autowired 20 | private ${clazz.bclassName}Dao ${clazz.className}Dao; 21 | 22 | @AfterClass 23 | public static void clean() { 24 | DBUtils.truncateTable("${clazz.className}"); 25 | } 26 | 27 | @Test 28 | public void save${clazz.bclassName}() throws Exception { 29 | ${clazz.bclassName} ${clazz.className} = ${clazz.bclassName}Data.generatOne(false); 30 | ${clazz.className}Dao.save${clazz.bclassName}(${clazz.className}); 31 | assertNotNull("${clazz.className} id is null", ${clazz.className}.getId()); 32 | log.warn("save${clazz.bclassName} run res : {}", JsonMapper.INSTANCE.toJson(${clazz.className})); 33 | } 34 | 35 | @Test 36 | public void remove${clazz.bclassName}() throws Exception { 37 | ${clazz.bclassName} ${clazz.className} = ${clazz.bclassName}Data.generatOne(false); 38 | ${clazz.className}Dao.save${clazz.bclassName}(${clazz.className}); 39 | assertNotNull("${clazz.className} id is null", ${clazz.className}.getId()); 40 | ${clazz.className}Dao.remove${clazz.bclassName}(${clazz.className}.getId()); 41 | ${clazz.bclassName} null${clazz.bclassName} = ${clazz.className}Dao.find${clazz.bclassName}ById(${clazz.className}.getId()); 42 | assertNull("${clazz.className} is remove", null${clazz.bclassName}); 43 | } 44 | 45 | @Test 46 | public void update${clazz.bclassName}() throws Exception { 47 | ${clazz.bclassName} ${clazz.className} = ${clazz.bclassName}Data.generatOne(false); 48 | ${clazz.className}Dao.save${clazz.bclassName}(${clazz.className}); 49 | ${clazz.bclassName} update${clazz.bclassName} = ${clazz.bclassName}Data.generatOne(false); 50 | update${clazz.bclassName}.setId(${clazz.className}.getId()); 51 | ${clazz.className}Dao.update${clazz.bclassName}(update${clazz.bclassName}); 52 | ${clazz.bclassName} select${clazz.bclassName} = ${clazz.className}Dao.find${clazz.bclassName}ById(${clazz.className}.getId()); 53 | assertEquals("must equals", select${clazz.bclassName}.getId(), update${clazz.bclassName}.getId()); 54 | } 55 | 56 | @Test 57 | public void find${clazz.bclassName}ById() throws Exception { 58 | ${clazz.bclassName} ${clazz.className} = ${clazz.bclassName}Data.generatOne(false); 59 | ${clazz.className}Dao.save${clazz.bclassName}(${clazz.className}); 60 | 61 | ${clazz.bclassName} select${clazz.bclassName} = ${clazz.className}Dao.find${clazz.bclassName}ById(${clazz.className}.getId()); 62 | assertNotNull("${clazz.className}Id should not be null", select${clazz.bclassName}.getId()); 63 | assertNotNull("${clazz.className} should not be null", select${clazz.bclassName}); 64 | log.warn("find${clazz.bclassName}ById res : {}", JsonMapper.INSTANCE.toJson(${clazz.className})); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/db/dataTemplate.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.data; 2 | 3 | import ${projectPackage}.domain.${clazz.bclassName}; 4 | import com.vip.vjtools.vjkit.number.RandomUtil; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Date; 8 | import java.util.List; 9 | 10 | /** 11 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 12 | */ 13 | public class ${clazz.bclassName}Data { 14 | 15 | public static List<${clazz.bclassName}> generatList(int num, boolean withId) { 16 | List<${clazz.bclassName}> resultList = new ArrayList<>(); 17 | for (int i = 0; i < num; i++) { 18 | resultList.add(generatOne(withId, null)); 19 | } 20 | return resultList; 21 | } 22 | 23 | public static ${clazz.bclassName} generatOne(boolean withId) { 24 | return generatOne(withId, null); 25 | } 26 | 27 | public static ${clazz.bclassName} generatOneWithGivenId(${clazz.idType} withGivenId) { 28 | return generatOne(false, withGivenId); 29 | } 30 | 31 | private static ${clazz.bclassName} generatOne(boolean withId, ${clazz.idType} withGivenId) { 32 | ${clazz.bclassName} ${clazz.className} = new ${clazz.bclassName}(); 33 | if (withId) { 34 | ${clazz.className}.setId(RandomUtil.next${clazz.idTypeSimple}()); 35 | } else { 36 | if (withGivenId != null) { 37 | ${clazz.className}.setId(withGivenId); 38 | } 39 | } 40 | <#list clazz.fieldList as field> 41 | <#if field.tname != "id"> 42 | ${clazz.className}.set${field.bname}(<#compress><@calcLen f=field/>); 43 | 44 | 45 | return ${clazz.className}; 46 | } 47 | } 48 | 49 | <#macro calcLen f> 50 | <#if f.classType == "String"> 51 | <#if f.maxRandomLen gt 0>"${f.tname}_" + RandomUtil.randomStringFixLength(${f.maxRandomLen}) 52 | <#else>RandomUtil.randomStringFixLength(${f.maxRandomLen?abs}) 53 | 54 | <#elseif f.classType == "Long">RandomUtil.nextLong() 55 | <#elseif f.classType == "Integer">RandomUtil.nextInt(10) 56 | <#elseif f.classType == "Float">RandomUtil.nextDouble(200d); 57 | <#elseif f.classType == "Double">RandomUtil.nextDouble(200d); 58 | <#elseif f.classType == "java.math.BigDecimal">new java.math.BigDecimal(String.valueOf(RandomUtil.nextDouble(200d))) 59 | <#elseif f.classType == "java.util.Date">new Date() 60 | <#elseif f.classType == "java.sql.Timestamp">new java.sql.Timestamp() 61 | <#elseif f.classType == "byte[]">RandomUtil.randomStringFixLength(10).getBytes() 62 | <#else>RandomUtil.randomStringFixLength(${f.maxRandomLen}) 63 | 64 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/db/entityTemplate.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.domain; 2 | 3 | import java.io.Serializable; 4 | /** 5 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 6 | */ 7 | public class ${clazz.bclassName} implements Serializable { 8 | 9 | private static final long serialVersionUID = 1L; 10 | 11 | <#list clazz.fieldList as field> 12 | /** 13 | * ${field.desc} 14 | */ 15 | private ${field.classType} ${field.name}; 16 | 17 | 18 | <#list clazz.fieldList as field> 19 | public void set${field.bname}(${field.classType} ${field.name}) { 20 | this.${field.name} = ${field.name}; 21 | } 22 | 23 | public ${field.classType} get${field.bname}() { 24 | return ${field.name}; 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/db/mapperTemplate.ftl: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | <#list clazz.tablefieldList as field> 8 | 9 | 10 | 11 | 12 | 13 | <#list clazz.tablefieldList as field> 14 | ${field.tname}, 15 | 16 | 17 | 18 | 19 | 20 | <#list clazz.tablefieldList as field> 21 | ${r"#"}{${field.name}}, 22 | 23 | 24 | 25 | 26 | 27 | <#list clazz.tablefieldList as field> 28 | ${field.tname}, 29 | 30 | 31 | 32 | 34 | 35 | SELECT LAST_INSERT_ID() 36 | 37 | insert into ${clazz.tableName} () 38 | values () 39 | 40 | 41 | update ${clazz.tableName} 42 | 43 | <#list clazz.insertfieldList as field> 44 | ${field.tname}=${r"#"}{${field.name}}<#if field_has_next>, 45 | 46 | 47 | where id = ${r"#"}{id} 48 | 49 | 50 | delete from ${clazz.tableName} 51 | where id = ${r"#"}{id} 52 | 53 | 59 | 60 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/db/saveOrUpdateReqTemplate.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.web.req; 2 | 3 | /** 4 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 5 | */ 6 | public class SaveOrUpdate${clazz.bclassName} { 7 | 8 | <#list clazz.fieldList as field> 9 | /** 10 | * ${field.desc} 11 | */ 12 | private ${field.classType} ${field.name}; 13 | 14 | 15 | <#list clazz.fieldList as field> 16 | public void set${field.bname}(${field.classType} ${field.name}) { 17 | this.${field.name} = ${field.name}; 18 | } 19 | 20 | public ${field.classType} get${field.bname}() { 21 | return ${field.name}; 22 | } 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/db/serviceImplTemplate.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.service.impl; 2 | 3 | import ${projectPackage}.common.exception.BizException; 4 | import ${projectPackage}.constant.ErrorEnum; 5 | import ${projectPackage}.domain.${clazz.bclassName}; 6 | import ${projectPackage}.dao.${clazz.bclassName}Dao; 7 | import ${projectPackage}.service.${clazz.bclassName}Service; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Service; 10 | 11 | /** 12 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 13 | */ 14 | @Service 15 | public class ${clazz.bclassName}ServiceImpl implements ${clazz.bclassName}Service { 16 | 17 | @Autowired 18 | private ${clazz.bclassName}Dao ${clazz.className}Dao; 19 | 20 | @Override 21 | public ${clazz.bclassName} save${clazz.bclassName}(${clazz.bclassName} ${clazz.className}) { 22 | int result = ${clazz.className}Dao.save${clazz.bclassName}(${clazz.className}); 23 | if(result == 0){ 24 | BizException.throwOut(ErrorEnum.DB_FAIL); 25 | } 26 | return ${clazz.className}; 27 | } 28 | 29 | @Override 30 | public Integer update${clazz.bclassName}(${clazz.bclassName} ${clazz.className}) { 31 | int result = ${clazz.className}Dao.update${clazz.bclassName}(${clazz.className}); 32 | if(result == 0){ 33 | BizException.throwOut(ErrorEnum.DB_FAIL); 34 | } 35 | return result; 36 | } 37 | 38 | @Override 39 | public Integer remove${clazz.bclassName}(${clazz.idType} id) { 40 | int result = ${clazz.className}Dao.remove${clazz.bclassName}(id); 41 | if(result == 0){ 42 | BizException.throwOut(ErrorEnum.DB_FAIL); 43 | } 44 | return result; 45 | } 46 | 47 | @Override 48 | public ${clazz.bclassName} find${clazz.bclassName}ById(${clazz.idType} id) { 49 | ${clazz.bclassName} ${clazz.className} = ${clazz.className}Dao.find${clazz.bclassName}ById(id); 50 | if (${clazz.className} == null) { 51 | BizException.throwOut(ErrorEnum.DB_FAIL); 52 | } 53 | return ${clazz.className}; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/db/serviceTemplate.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.service; 2 | 3 | import ${projectPackage}.domain.${clazz.bclassName}; 4 | 5 | /** 6 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 7 | */ 8 | public interface ${clazz.bclassName}Service { 9 | 10 | ${clazz.bclassName} save${clazz.bclassName}(${clazz.bclassName} ${clazz.className}); 11 | 12 | Integer remove${clazz.bclassName}(${clazz.idType} id); 13 | 14 | Integer update${clazz.bclassName}(${clazz.bclassName} ${clazz.className}); 15 | 16 | ${clazz.bclassName} find${clazz.bclassName}ById(${clazz.idType} id); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/gitIgnore.ftl: -------------------------------------------------------------------------------- 1 | # Eclipse project files 2 | .classpath 3 | .project 4 | .settings/ 5 | 6 | # Intellij project files 7 | *.iml 8 | .idea/ 9 | 10 | # Others 11 | target/ 12 | logs/ 13 | 14 | # Package Files 15 | *.jar 16 | *.war 17 | *.ear 18 | *.DS_Store 19 | *.class 20 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/gitkeep.ftl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vancefantasy/flyer-maker/5242400cb05a71b87f4bac8b6ace18ef98eb41c3/src/main/java/com/flyer/maker/freemarker/templete/gitkeep.ftl -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springboot-rest/AbstractMVCTest.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.mockito.MockitoAnnotations; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; 11 | import org.springframework.boot.test.context.SpringBootTest; 12 | import org.springframework.test.context.ActiveProfiles; 13 | import org.springframework.test.context.junit4.SpringRunner; 14 | import org.springframework.test.web.servlet.MockMvc; 15 | 16 | /** 17 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 18 | */ 19 | @ActiveProfiles("ut") 20 | @RunWith(SpringRunner.class) 21 | @SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT) 22 | @AutoConfigureMockMvc 23 | public class AbstractMVCTest { 24 | 25 | protected Logger log = LoggerFactory.getLogger(getClass()); 26 | 27 | @Autowired 28 | protected MockMvc mockMvc; 29 | 30 | private static boolean checkDBNameDone = false; 31 | 32 | @Before 33 | public void setUp() { 34 | if (!checkDBNameDone){ 35 | DBUtils.checkDBName(); 36 | checkDBNameDone = true; 37 | } 38 | MockitoAnnotations.initMocks(this); 39 | } 40 | 41 | @Test 42 | public void nothing() { 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springboot-rest/AbstractTest.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.test.context.ActiveProfiles; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | /** 13 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 14 | */ 15 | @ActiveProfiles("ut") 16 | @SpringBootTest 17 | @RunWith(SpringRunner.class) 18 | public class AbstractTest { 19 | 20 | protected Logger log = LoggerFactory.getLogger(getClass()); 21 | 22 | private static boolean checkDBNameDone = false; 23 | 24 | @Before 25 | public void setUp() { 26 | if (!checkDBNameDone) { 27 | DBUtils.checkDBName(); 28 | checkDBNameDone = true; 29 | } 30 | } 31 | 32 | @Test 33 | public void nothing() { 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springboot-rest/App.java.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 8 | import org.springframework.context.annotation.ComponentScan; 9 | import uk.org.lidalia.sysoutslf4j.context.SysOutOverSLF4J; 10 | 11 | /** 12 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 13 | */ 14 | @SpringBootApplication 15 | @EnableAutoConfiguration 16 | @MapperScan("${projectPackage}.dao") 17 | @ComponentScan("${projectPackage}") 18 | public class App extends SpringBootServletInitializer { 19 | 20 | public static void main(String[] args) { 21 | SpringApplication.run(App.class, args); 22 | //console -> slf4j 23 | SysOutOverSLF4J.sendSystemOutAndErrToSLF4J(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springboot-rest/WebMvcConfig.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.common; 2 | 3 | import ${projectPackage}.common.interceptor.ControllerInterceptor; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.filter.CharacterEncodingFilter; 7 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 9 | 10 | import javax.servlet.Filter; 11 | 12 | /** 13 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 14 | */ 15 | @Configuration 16 | public class WebMvcConfig implements WebMvcConfigurer { 17 | 18 | @Override 19 | public void addInterceptors(InterceptorRegistry registry) { 20 | registry.addInterceptor(new ControllerInterceptor()).addPathPatterns("/**") 21 | .excludePathPatterns("/", "/healthCheck"); 22 | } 23 | 24 | @Bean 25 | public Filter characterEncodingFilter() { 26 | CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); 27 | characterEncodingFilter.setEncoding("UTF-8"); 28 | characterEncodingFilter.setForceEncoding(true); 29 | return characterEncodingFilter; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springboot-rest/application-dev.properties.ftl: -------------------------------------------------------------------------------- 1 | #dev 2 | #server 3 | server.port=8080 4 | #logs 5 | logs.home=/tmp/dev/${projectArtifactId} 6 | #datasource 7 | spring.datasource.type=com.alibaba.druid.pool.DruidDataSource 8 | spring.datasource.url=${mysqlJdbcUrl} 9 | spring.datasource.username=${mysqlUsername} 10 | spring.datasource.password=${mysqlPassword} 11 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 12 | spring.datasource.initialSize=2 13 | spring.datasource.minIdle=2 14 | spring.datasource.maxActive=2 15 | spring.datasource.maxWait=60000 16 | spring.datasource.timeBetweenEvictionRunsMillis=60000 17 | spring.datasource.minEvictableIdleTimeMillis=300000 18 | spring.datasource.validationQuery=SELECT 1 FROM DUAL 19 | spring.datasource.testWhileIdle=true 20 | spring.datasource.testOnBorrow=false 21 | spring.datasource.testOnReturn=false 22 | spring.datasource.poolPreparedStatements=true 23 | spring.datasource.maxPoolPreparedStatementPerConnectionSize=20 24 | spring.datasource.filters=stat,wall,log4j 25 | spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 26 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springboot-rest/application-prod.properties.ftl: -------------------------------------------------------------------------------- 1 | #prod 2 | #server 3 | server.port=8080 4 | #logs 5 | logs.home=/tmp/prod/${projectArtifactId} 6 | #datasource 7 | spring.datasource.type=com.alibaba.druid.pool.DruidDataSource 8 | spring.datasource.url=${mysqlJdbcUrl} 9 | spring.datasource.username=${mysqlUsername} 10 | spring.datasource.password=${mysqlPassword} 11 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 12 | spring.datasource.initialSize=2 13 | spring.datasource.minIdle=2 14 | spring.datasource.maxActive=2 15 | spring.datasource.maxWait=60000 16 | spring.datasource.timeBetweenEvictionRunsMillis=60000 17 | spring.datasource.minEvictableIdleTimeMillis=300000 18 | spring.datasource.validationQuery=SELECT 1 FROM DUAL 19 | spring.datasource.testWhileIdle=true 20 | spring.datasource.testOnBorrow=false 21 | spring.datasource.testOnReturn=false 22 | spring.datasource.poolPreparedStatements=true 23 | spring.datasource.maxPoolPreparedStatementPerConnectionSize=20 24 | spring.datasource.filters=stat,wall,log4j 25 | spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 26 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springboot-rest/application-stage.properties.ftl: -------------------------------------------------------------------------------- 1 | #stage 2 | #server 3 | server.port=8080 4 | #logs 5 | logs.home=/tmp/stage/${projectArtifactId} 6 | #datasource 7 | spring.datasource.type=com.alibaba.druid.pool.DruidDataSource 8 | spring.datasource.url=${mysqlJdbcUrl} 9 | spring.datasource.username=${mysqlUsername} 10 | spring.datasource.password=${mysqlPassword} 11 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 12 | spring.datasource.initialSize=2 13 | spring.datasource.minIdle=2 14 | spring.datasource.maxActive=2 15 | spring.datasource.maxWait=60000 16 | spring.datasource.timeBetweenEvictionRunsMillis=60000 17 | spring.datasource.minEvictableIdleTimeMillis=300000 18 | spring.datasource.validationQuery=SELECT 1 FROM DUAL 19 | spring.datasource.testWhileIdle=true 20 | spring.datasource.testOnBorrow=false 21 | spring.datasource.testOnReturn=false 22 | spring.datasource.poolPreparedStatements=true 23 | spring.datasource.maxPoolPreparedStatementPerConnectionSize=20 24 | spring.datasource.filters=stat,wall,log4j 25 | spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 26 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springboot-rest/application-test.properties.ftl: -------------------------------------------------------------------------------- 1 | #test 2 | #server 3 | server.port=8080 4 | #logs 5 | logs.home=/tmp/test/${projectArtifactId} 6 | #datasource 7 | spring.datasource.type=com.alibaba.druid.pool.DruidDataSource 8 | spring.datasource.url=${mysqlJdbcUrl} 9 | spring.datasource.username=${mysqlUsername} 10 | spring.datasource.password=${mysqlPassword} 11 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 12 | spring.datasource.initialSize=2 13 | spring.datasource.minIdle=2 14 | spring.datasource.maxActive=2 15 | spring.datasource.maxWait=60000 16 | spring.datasource.timeBetweenEvictionRunsMillis=60000 17 | spring.datasource.minEvictableIdleTimeMillis=300000 18 | spring.datasource.validationQuery=SELECT 1 FROM DUAL 19 | spring.datasource.testWhileIdle=true 20 | spring.datasource.testOnBorrow=false 21 | spring.datasource.testOnReturn=false 22 | spring.datasource.poolPreparedStatements=true 23 | spring.datasource.maxPoolPreparedStatementPerConnectionSize=20 24 | spring.datasource.filters=stat,wall,log4j 25 | spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 26 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springboot-rest/application.properties.ftl: -------------------------------------------------------------------------------- 1 | #set profile=dev 2 | spring.profiles.active=dev 3 | spring.application.name=${projectArtifactId} 4 | #mybatis 5 | mybatis.type-aliases-package=${projectPackage}.domain 6 | mybatis.mapper-locations=classpath:/mapper/*.xml 7 | mybatis.configuration.map-underscore-to-camel-case=true 8 | mybatis.configuration.use-generated-keys=true 9 | mybatis.configuration.default-fetch-size=100 10 | mybatis.configuration.default-statement-timeout=30 11 | #jackson 12 | spring.jackson.date-format=yyyy-MM-dd HH:mm:ss 13 | spring.jackson.time-zone=GMT+8 14 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springboot-rest/logback-spring.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | %d{yyyy-MM-dd HH:mm:ss.SSS} %boldYellow([%thread]) %highlight(%-5level) %boldGreen(%logger{36}): - %msg%n 10 | 11 | 12 | 13 | 14 | 15 | 16 | DEBUG 17 | DENY 18 | ACCEPT 19 | 20 | 21 | ${r"$"}{LOG_HOME}/${projectArtifactId}_debug.%d{yyyy-MM-dd}.log 22 | 10 23 | 24 | 25 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}: - %msg%n 26 | 27 | 28 | 29 | 30 | INFO 31 | 32 | 33 | ${r"$"}{LOG_HOME}/${projectArtifactId}_info.%d{yyyy-MM-dd}.log 34 | 10 35 | 36 | 37 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}: - %msg%n 38 | 39 | 40 | 41 | 42 | WARN 43 | 44 | 45 | ${r"$"}{LOG_HOME}/${projectArtifactId}_error.%d{yyyy-MM-dd}.log 46 | 10 47 | 48 | 49 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}: - %msg%n 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springboot-rest/logback-test.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %d{yyyy-MM-dd HH:mm:ss.SSS} %boldYellow([%thread]) %highlight(%-5level) %boldGreen(%logger{36}): - %msg%n 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springboot-rest/pom.ftl: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | ${projectGroupId} 7 | ${projectArtifactId} 8 | 0.0.1 9 | jar 10 | ${projectArtifactId} 11 | 12 | org.springframework.boot 13 | spring-boot-starter-parent 14 | 2.0.5.RELEASE 15 | 16 | 17 | 18 | UTF-8 19 | UTF-8 20 | 1.8 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-data-redis 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-web 30 | 31 | 32 | org.mybatis.spring.boot 33 | mybatis-spring-boot-starter 34 | 1.3.2 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-devtools 39 | runtime 40 | 41 | 42 | com.github.pagehelper 43 | pagehelper 44 | 5.1.4 45 | 46 | 47 | mysql 48 | mysql-connector-java 49 | runtime 50 | 51 | 52 | uk.org.lidalia 53 | sysout-over-slf4j 54 | 1.0.2 55 | 56 | 57 | slf4j-api 58 | org.slf4j 59 | 60 | 61 | 62 | 63 | com.alibaba 64 | druid 65 | 1.0.20 66 | 67 | 68 | commons-codec 69 | commons-codec 70 | 1.11 71 | 72 | 73 | org.apache.commons 74 | commons-lang3 75 | 3.7 76 | 77 | 78 | commons-io 79 | commons-io 80 | 2.6 81 | 82 | 83 | joda-time 84 | joda-time 85 | 86 | 87 | com.vip.vjtools 88 | vjkit 89 | 1.0.5 90 | 91 | 92 | slf4j-api 93 | org.slf4j 94 | 95 | 96 | 97 | 98 | org.jodd 99 | jodd-all 100 | 5.0.4 101 | 102 | 103 | org.springframework.boot 104 | spring-boot-starter-test 105 | test 106 | 107 | 108 | javax.inject 109 | javax.inject 110 | 1 111 | test 112 | 113 | 114 | 115 | ${projectArtifactId} 116 | 117 | 118 | org.springframework.boot 119 | spring-boot-maven-plugin 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springboot-rest/serviceImplTestTemplate.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.service.impl; 2 | 3 | import ${projectPackage}.AbstractTest; 4 | import ${projectPackage}.dao.${clazz.bclassName}Dao; 5 | import ${projectPackage}.data.${clazz.bclassName}Data; 6 | import ${projectPackage}.domain.${clazz.bclassName}; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | import org.mockito.InjectMocks; 10 | import org.mockito.MockitoAnnotations; 11 | import org.springframework.boot.test.mock.mockito.MockBean; 12 | 13 | import javax.inject.Inject; 14 | 15 | import static org.hamcrest.CoreMatchers.is; 16 | import static org.hamcrest.CoreMatchers.notNullValue; 17 | import static org.junit.Assert.assertThat; 18 | import static org.mockito.Matchers.any; 19 | import static org.mockito.Matchers.anyInt; 20 | import static org.mockito.Matchers.anyLong; 21 | import static org.mockito.Mockito.*; 22 | 23 | /** 24 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 25 | */ 26 | public class ${clazz.bclassName}ServiceImplTest extends AbstractTest { 27 | 28 | @MockBean 29 | private ${clazz.bclassName}Dao ${clazz.className}Dao; 30 | 31 | @Inject 32 | @InjectMocks 33 | private ${clazz.bclassName}ServiceImpl ${clazz.className}Service; 34 | 35 | @Before 36 | public void setUp() { 37 | MockitoAnnotations.initMocks(this); 38 | } 39 | 40 | @Test 41 | public void save${clazz.bclassName}() throws Exception { 42 | when(${clazz.className}Dao.save${clazz.bclassName}(any(${clazz.bclassName}.class))).thenReturn(1); 43 | assertThat(${clazz.className}Service.save${clazz.bclassName}(${clazz.bclassName}Data.generatOne(true)), is(notNullValue())); 44 | verify(${clazz.className}Dao, times(1)).save${clazz.bclassName}(any(${clazz.bclassName}.class)); 45 | } 46 | 47 | @Test 48 | public void remove${clazz.bclassName}() throws Exception { 49 | when(${clazz.className}Dao.remove${clazz.bclassName}(any${clazz.idTypeSimple}())).thenReturn(1); 50 | assertThat(${clazz.className}Service.remove${clazz.bclassName}(any${clazz.idTypeSimple}()), is(1)); 51 | verify(${clazz.className}Dao, times(1)).remove${clazz.bclassName}(any${clazz.idTypeSimple}()); 52 | } 53 | 54 | @Test 55 | public void update${clazz.bclassName}() throws Exception { 56 | when(${clazz.className}Dao.update${clazz.bclassName}(any(${clazz.bclassName}.class))).thenReturn(1); 57 | assertThat(${clazz.className}Service.update${clazz.bclassName}(${clazz.bclassName}Data.generatOne(true)), is(1)); 58 | verify(${clazz.className}Dao, times(1)).update${clazz.bclassName}(any(${clazz.bclassName}.class)); 59 | } 60 | 61 | @Test 62 | public void find${clazz.bclassName}ById() throws Exception { 63 | when(${clazz.className}Dao.find${clazz.bclassName}ById(any${clazz.idTypeSimple}())).thenReturn(${clazz.bclassName}Data.generatOne(true)); 64 | assertThat(${clazz.className}Service.find${clazz.bclassName}ById(any${clazz.idTypeSimple}()), is(notNullValue())); 65 | verify(${clazz.className}Dao, times(1)).find${clazz.bclassName}ById(any${clazz.idTypeSimple}()); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springboot-rest/unit_application.properties.ftl: -------------------------------------------------------------------------------- 1 | #dev 2 | server.port=8080 3 | #datasource 4 | spring.datasource.type=com.alibaba.druid.pool.DruidDataSource 5 | spring.datasource.url=jdbc:mysql://localhost:3306/flyer_ut?useUnicode=true&characterEncoding=utf-8&useSSL=false 6 | spring.datasource.username=flyer_w 7 | spring.datasource.password=123456 8 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 9 | spring.datasource.initialSize=2 10 | spring.datasource.minIdle=2 11 | spring.datasource.maxActive=2 12 | spring.datasource.maxWait=60000 13 | spring.datasource.timeBetweenEvictionRunsMillis=60000 14 | spring.datasource.minEvictableIdleTimeMillis=300000 15 | spring.datasource.validationQuery=SELECT 1 FROM DUAL 16 | spring.datasource.testWhileIdle=true 17 | spring.datasource.testOnBorrow=false 18 | spring.datasource.testOnReturn=false 19 | #mybatis 20 | mybatis.type-aliases-package=${projectPackage}.domain 21 | mybatis.mapper-locations=classpath:/mapper/*.xml 22 | mybatis.configuration.map-underscore-to-camel-case=true 23 | mybatis.configuration.use-generated-keys=true 24 | mybatis.configuration.default-fetch-size=100 25 | mybatis.configuration.default-statement-timeout=30 26 | #jackson 27 | spring.jackson.date-format=yyyy-MM-dd HH:mm:ss 28 | spring.jackson.time-zone=GMT+8 29 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/AbstractMVCTest.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.mockito.MockitoAnnotations; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.test.context.ActiveProfiles; 11 | import org.springframework.test.context.ContextConfiguration; 12 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 13 | import org.springframework.test.context.web.WebAppConfiguration; 14 | import org.springframework.test.web.servlet.MockMvc; 15 | import org.springframework.test.web.servlet.setup.MockMvcBuilders; 16 | import org.springframework.web.context.WebApplicationContext; 17 | 18 | /** 19 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 20 | */ 21 | @ActiveProfiles("ut") 22 | @RunWith(SpringJUnit4ClassRunner.class) 23 | @WebAppConfiguration 24 | @ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring-servlet.xml", 25 | "classpath:/base/spring-bootstrap.xml"}) 26 | public class AbstractMVCTest { 27 | 28 | protected Logger log = LoggerFactory.getLogger(getClass()); 29 | 30 | @Autowired 31 | private WebApplicationContext wac; 32 | 33 | protected MockMvc mockMvc; 34 | 35 | private static boolean checkDBNameDone = false; 36 | 37 | @Before 38 | public void setUp() { 39 | if (!checkDBNameDone){ 40 | DBUtils.checkDBName(); 41 | checkDBNameDone = true; 42 | } 43 | MockitoAnnotations.initMocks(this); 44 | mockMvc = MockMvcBuilders.webAppContextSetup(wac).build(); 45 | } 46 | 47 | @Test 48 | public void nothing() { 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/AbstractTest.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.test.context.ActiveProfiles; 9 | import org.springframework.test.context.ContextConfiguration; 10 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 11 | 12 | /** 13 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 14 | */ 15 | @ActiveProfiles("ut") 16 | @RunWith(SpringJUnit4ClassRunner.class) 17 | @ContextConfiguration({"classpath:/base/spring-bootstrap.xml"}) 18 | public class AbstractTest { 19 | 20 | protected Logger log = LoggerFactory.getLogger(getClass()); 21 | 22 | private static boolean checkDBNameDone = false; 23 | 24 | @Before 25 | public void setUp() { 26 | if (!checkDBNameDone) { 27 | DBUtils.checkDBName(); 28 | checkDBNameDone = true; 29 | } 30 | } 31 | 32 | @Test 33 | public void nothing() { 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/dev_config.properties.ftl: -------------------------------------------------------------------------------- 1 | #dev 2 | #mysql 3 | mysql.jdbc.url=${mysqlJdbcUrl} 4 | mysql.jdbc.username=${mysqlUsername} 5 | mysql.jdbc.password=${mysqlPassword} 6 | mysql.jdbc.initialSize=2 7 | mysql.jdbc.minIdle=2 8 | mysql.jdbc.maxActive=2 9 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/dev_logback.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %d{yyyy-MM-dd HH:mm:ss.SSS} %boldYellow([%thread]) %highlight(%-5level) 6 | %boldGreen(%logger{36}): - %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/logback-test.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %d{yyyy-MM-dd HH:mm:ss.SSS} %boldYellow([%thread]) %highlight(%-5level) %boldGreen(%logger{36}): - %msg%n 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/pom.ftl: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | ${projectGroupId} 7 | ${projectArtifactId} 8 | 0.0.1 9 | ${projectArtifactId} 10 | war 11 | 12 | 1.8 13 | 4.3.18.RELEASE 14 | UTF-8 15 | 16 | 17 | 18 | org.springframework 19 | spring-webmvc 20 | ${r"$"}{spring.version} 21 | 22 | 23 | org.springframework 24 | spring-context-support 25 | ${r"$"}{spring.version} 26 | 27 | 28 | org.springframework 29 | spring-jdbc 30 | ${r"$"}{spring.version} 31 | 32 | 33 | org.aspectj 34 | aspectjrt 35 | 1.7.3 36 | 37 | 38 | org.aspectj 39 | aspectjweaver 40 | 1.7.3 41 | 42 | 43 | aopalliance 44 | aopalliance 45 | 1.0 46 | 47 | 48 | org.mybatis 49 | mybatis 50 | 3.4.0 51 | 52 | 53 | org.mybatis 54 | mybatis-spring 55 | 1.3.0 56 | 57 | 58 | mysql 59 | mysql-connector-java 60 | 5.1.45 61 | 62 | 63 | com.alibaba 64 | druid 65 | 1.1.10 66 | 67 | 68 | com.github.pagehelper 69 | pagehelper 70 | 5.1.4 71 | 72 | 73 | org.logback-extensions 74 | logback-ext-spring 75 | 0.1.4 76 | 77 | 78 | org.slf4j 79 | log4j-over-slf4j 80 | 1.7.6 81 | 82 | 83 | org.slf4j 84 | jcl-over-slf4j 85 | 1.7.6 86 | 87 | 88 | uk.org.lidalia 89 | sysout-over-slf4j 90 | 1.0.2 91 | 92 | 93 | slf4j-api 94 | org.slf4j 95 | 96 | 97 | 98 | 99 | com.fasterxml.jackson.core 100 | jackson-databind 101 | 2.8.11.1 102 | 103 | 104 | com.google.code.gson 105 | gson 106 | 2.2.4 107 | 108 | 109 | joda-time 110 | joda-time 111 | 2.7 112 | 113 | 114 | commons-codec 115 | commons-codec 116 | 1.11 117 | 118 | 119 | org.apache.commons 120 | commons-lang3 121 | 3.7 122 | 123 | 124 | commons-io 125 | commons-io 126 | 2.6 127 | 128 | 129 | javax.servlet 130 | javax.servlet-api 131 | 3.0.1 132 | provided 133 | 134 | 135 | com.vip.vjtools 136 | vjkit 137 | 1.0.5 138 | 139 | 140 | slf4j-api 141 | org.slf4j 142 | 143 | 144 | 145 | 146 | org.jodd 147 | jodd-all 148 | 5.0.4 149 | 150 | 151 | javax.mail 152 | mail 153 | 1.4.3 154 | 155 | 156 | org.hibernate 157 | hibernate-validator 158 | 5.4.2.Final 159 | 160 | 161 | junit 162 | junit 163 | 4.12 164 | test 165 | 166 | 167 | org.springframework 168 | spring-test 169 | ${r"$"}{spring.version} 170 | test 171 | 172 | 173 | spring-core 174 | org.springframework 175 | 176 | 177 | 178 | 179 | org.mockito 180 | mockito-all 181 | 1.9.5 182 | test 183 | 184 | 185 | com.jayway.jsonpath 186 | json-path 187 | 2.2.0 188 | test 189 | 190 | 191 | slf4j-api 192 | org.slf4j 193 | 194 | 195 | 196 | 197 | javax.inject 198 | javax.inject 199 | 1 200 | test 201 | 202 | 203 | 204 | ${projectArtifactId} 205 | 206 | 207 | org.apache.maven.plugins 208 | maven-compiler-plugin 209 | 3.7.0 210 | 211 | ${r"$"}{java.version} 212 | ${r"$"}{java.version} 213 | 214 | 215 | 216 | 217 | 218 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/prod_config.properties.ftl: -------------------------------------------------------------------------------- 1 | #prod 2 | #mysql 3 | mysql.jdbc.url=${mysqlJdbcUrl} 4 | mysql.jdbc.username=${mysqlUsername} 5 | mysql.jdbc.password=${mysqlPassword} 6 | mysql.jdbc.initialSize=2 7 | mysql.jdbc.minIdle=2 8 | mysql.jdbc.maxActive=2 9 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/prod_logback.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | DEBUG 8 | DENY 9 | ACCEPT 10 | 11 | 12 | ${r"$"}{LOG_HOME}/${projectArtifactId}_debug.%d{yyyy-MM-dd}.log 13 | 30 14 | 15 | 16 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}: - %msg%n 17 | 18 | 19 | 20 | 21 | INFO 22 | 23 | 24 | ${r"$"}{LOG_HOME}/${projectArtifactId}_info.%d{yyyy-MM-dd}.log 25 | 30 26 | 27 | 28 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}: - %msg%n 29 | 30 | 31 | 32 | 33 | WARN 34 | 35 | 36 | ${r"$"}{LOG_HOME}/${projectArtifactId}_error.%d{yyyy-MM-dd}.log 37 | 30 38 | 39 | 40 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}: - %msg%n 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/serviceImplTestTemplate.ftl: -------------------------------------------------------------------------------- 1 | package ${projectPackage}.service.impl; 2 | 3 | import ${projectPackage}.AbstractTest; 4 | import ${projectPackage}.domain.${clazz.bclassName}; 5 | import ${projectPackage}.data.${clazz.bclassName}Data; 6 | import ${projectPackage}.dao.${clazz.bclassName}Dao; 7 | import ${projectPackage}.service.${clazz.bclassName}Service; 8 | import org.junit.Before; 9 | import org.junit.Test; 10 | import org.mockito.InjectMocks; 11 | import org.mockito.Mock; 12 | import org.mockito.MockitoAnnotations; 13 | 14 | import javax.inject.Inject; 15 | 16 | import static org.hamcrest.CoreMatchers.is; 17 | import static org.hamcrest.CoreMatchers.notNullValue; 18 | import static org.junit.Assert.*; 19 | import static org.mockito.Matchers.any; 20 | import static org.mockito.Matchers.anyLong; 21 | import static org.mockito.Matchers.anyInt; 22 | import static org.mockito.Mockito.times; 23 | import static org.mockito.Mockito.verify; 24 | import static org.mockito.Mockito.when; 25 | 26 | /** 27 | * Created by ${author} on ${.now?string('yyyy/MM/dd')}. 28 | */ 29 | public class ${clazz.bclassName}ServiceImplTest extends AbstractTest { 30 | 31 | @Mock 32 | private ${clazz.bclassName}Dao ${clazz.className}Dao; 33 | 34 | @InjectMocks 35 | @Inject 36 | private ${clazz.bclassName}Service ${clazz.className}Service; 37 | 38 | @Before 39 | public void setUp() { 40 | MockitoAnnotations.initMocks(this); 41 | } 42 | 43 | @Test 44 | public void save${clazz.bclassName}() throws Exception { 45 | when(${clazz.className}Dao.save${clazz.bclassName}(any(${clazz.bclassName}.class))).thenReturn(1); 46 | assertThat(${clazz.className}Service.save${clazz.bclassName}(${clazz.bclassName}Data.generatOne(true)), is(notNullValue())); 47 | verify(${clazz.className}Dao, times(1)).save${clazz.bclassName}(any(${clazz.bclassName}.class)); 48 | } 49 | 50 | @Test 51 | public void remove${clazz.bclassName}() throws Exception { 52 | when(${clazz.className}Dao.remove${clazz.bclassName}(any${clazz.idTypeSimple}())).thenReturn(1); 53 | assertThat(${clazz.className}Service.remove${clazz.bclassName}(any${clazz.idTypeSimple}()), is(1)); 54 | verify(${clazz.className}Dao, times(1)).remove${clazz.bclassName}(any${clazz.idTypeSimple}()); 55 | } 56 | 57 | @Test 58 | public void update${clazz.bclassName}() throws Exception { 59 | when(${clazz.className}Dao.update${clazz.bclassName}(any(${clazz.bclassName}.class))).thenReturn(1); 60 | assertThat(${clazz.className}Service.update${clazz.bclassName}(${clazz.bclassName}Data.generatOne(true)), is(1)); 61 | verify(${clazz.className}Dao, times(1)).update${clazz.bclassName}(any(${clazz.bclassName}.class)); 62 | } 63 | 64 | @Test 65 | public void find${clazz.bclassName}ById() throws Exception { 66 | when(${clazz.className}Dao.find${clazz.bclassName}ById(any${clazz.idTypeSimple}())).thenReturn(${clazz.bclassName}Data.generatOne(true)); 67 | assertThat(${clazz.className}Service.find${clazz.bclassName}ById(any${clazz.idTypeSimple}()), is(notNullValue())); 68 | verify(${clazz.className}Dao, times(1)).find${clazz.bclassName}ById(any${clazz.idTypeSimple}()); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/spring-bootstrap.ftl: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/spring-core.ftl: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/spring-dao.ftl: -------------------------------------------------------------------------------- 1 | 2 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | helperDialect=mysql 40 | reasonable=true 41 | supportMethodsArguments=true 42 | params=count=countSql 43 | autoRuntimeDialect=true 44 | 45 | 46 | 47 | 48 | 49 | 50 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/spring-profile.ftl: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/spring-servlet.ftl: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | text/plain;charset=UTF-8 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | application/json;charset=UTF-8 34 | text/html;charset=UTF-8 35 | application/x-www-form-urlencoded 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/stage_config.properties.ftl: -------------------------------------------------------------------------------- 1 | #stage 2 | #mysql 3 | mysql.jdbc.url=${mysqlJdbcUrl} 4 | mysql.jdbc.username=${mysqlUsername} 5 | mysql.jdbc.password=${mysqlPassword} 6 | mysql.jdbc.initialSize=2 7 | mysql.jdbc.minIdle=2 8 | mysql.jdbc.maxActive=2 9 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/stage_logback.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | DEBUG 8 | DENY 9 | ACCEPT 10 | 11 | 12 | ${r"$"}{LOG_HOME}/${projectArtifactId}_debug.%d{yyyy-MM-dd}.log 13 | 30 14 | 15 | 16 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}: - %msg%n 17 | 18 | 19 | 20 | 21 | INFO 22 | 23 | 24 | ${r"$"}{LOG_HOME}/${projectArtifactId}_info.%d{yyyy-MM-dd}.log 25 | 30 26 | 27 | 28 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}: - %msg%n 29 | 30 | 31 | 32 | 33 | WARN 34 | 35 | 36 | ${r"$"}{LOG_HOME}/${projectArtifactId}_error.%d{yyyy-MM-dd}.log 37 | 30 38 | 39 | 40 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}: - %msg%n 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/test_config.properties.ftl: -------------------------------------------------------------------------------- 1 | #test 2 | #mysql 3 | mysql.jdbc.url=${mysqlJdbcUrl} 4 | mysql.jdbc.username=${mysqlUsername} 5 | mysql.jdbc.password=${mysqlPassword} 6 | mysql.jdbc.initialSize=2 7 | mysql.jdbc.minIdle=2 8 | mysql.jdbc.maxActive=2 9 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/test_logback.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | DEBUG 8 | DENY 9 | ACCEPT 10 | 11 | 12 | ${r"$"}{LOG_HOME}/${projectArtifactId}_debug.%d{yyyy-MM-dd}.log 13 | 30 14 | 15 | 16 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}: - %msg%n 17 | 18 | 19 | 20 | 21 | INFO 22 | 23 | 24 | ${r"$"}{LOG_HOME}/${projectArtifactId}_info.%d{yyyy-MM-dd}.log 25 | 30 26 | 27 | 28 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}: - %msg%n 29 | 30 | 31 | 32 | 33 | WARN 34 | 35 | 36 | ${r"$"}{LOG_HOME}/${projectArtifactId}_error.%d{yyyy-MM-dd}.log 37 | 30 38 | 39 | 40 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}: - %msg%n 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/unit_config.properties.ftl: -------------------------------------------------------------------------------- 1 | #ut 2 | #mysql 3 | mysql.jdbc.url=${mysqlJdbcUrl} 4 | mysql.jdbc.username=${mysqlUsername} 5 | mysql.jdbc.password=${mysqlPassword} 6 | mysql.jdbc.initialSize=2 7 | mysql.jdbc.minIdle=2 8 | mysql.jdbc.maxActive=2 9 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/freemarker/templete/springmvc-rest/webxml.ftl: -------------------------------------------------------------------------------- 1 | 2 | 6 | ${projectArtifactId} 7 | 8 | ${projectPackage}.common.listener.LogbackProfileListener 9 | 10 | 11 | org.springframework.web.util.IntrospectorCleanupListener 12 | 13 | 14 | org.springframework.web.context.ContextLoaderListener 15 | 16 | 17 | contextConfigLocation 18 | classpath:base/spring-bootstrap.xml 19 | 20 | 21 | springmvc 22 | org.springframework.web.servlet.DispatcherServlet 23 | 24 | contextConfigLocation 25 | /WEB-INF/spring-servlet.xml 26 | 27 | 1 28 | true 29 | 30 | 31 | springmvc 32 | /* 33 | 34 | 35 | encodingFilter 36 | org.springframework.web.filter.CharacterEncodingFilter 37 | true 38 | 39 | encoding 40 | UTF-8 41 | 42 | 43 | 44 | encodingFilter 45 | springmvc 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/generator/Generator.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker.generator; 2 | 3 | import freemarker.template.TemplateException; 4 | 5 | import java.io.IOException; 6 | 7 | /** 8 | * generator interface 9 | */ 10 | public interface Generator { 11 | 12 | void init() throws IOException; 13 | 14 | void generate() throws IOException, TemplateException; 15 | 16 | void base() throws IOException, TemplateException; 17 | 18 | void clearIfFail(); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/generator/GeneratorFactory.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker.generator; 2 | 3 | import com.flyer.maker.base.Config; 4 | import com.flyer.maker.generator.impl.BootPageGenerator; 5 | import com.flyer.maker.generator.impl.BootRestGenerator; 6 | import com.flyer.maker.generator.impl.MvcPageGenerator; 7 | import com.flyer.maker.generator.impl.MvcRestGenerator; 8 | 9 | /** 10 | * 生成器工厂类 11 | */ 12 | public class GeneratorFactory { 13 | 14 | public static Generator getGenerator() { 15 | switch (Config.projectType) { 16 | case "springmvc-rest": 17 | return new MvcRestGenerator(); 18 | case "springboot-rest": 19 | return new BootRestGenerator(); 20 | case "springmvc-page": 21 | return new MvcPageGenerator(); 22 | case "springboot-page": 23 | return new BootPageGenerator(); 24 | } 25 | return null; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/generator/impl/BaseGenerator.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker.generator.impl; 2 | 3 | import com.flyer.maker.base.Config; 4 | import com.flyer.maker.base.Clazz; 5 | import com.flyer.maker.generator.Generator; 6 | import com.flyer.maker.parser.impl.MySQLParser; 7 | import com.flyer.maker.parser.Parser; 8 | import com.flyer.maker.utils.GU; 9 | import freemarker.template.TemplateException; 10 | import org.apache.commons.io.FileUtils; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import java.io.File; 15 | import java.io.IOException; 16 | import java.util.HashMap; 17 | import java.util.List; 18 | import java.util.Map; 19 | 20 | /** 21 | * 基础生成器 22 | */ 23 | public abstract class BaseGenerator implements Generator { 24 | 25 | private final Logger log = LoggerFactory.getLogger(getClass()); 26 | 27 | protected String projectDir; 28 | protected String srcDir; 29 | protected String mainDir; 30 | protected String javaDir; 31 | protected String resourcesDir; 32 | protected String webappDir; 33 | protected String webInfDir; 34 | protected String basePackageDir; 35 | protected String testDir; 36 | protected String testJavaDir; 37 | protected String testResourcesDir; 38 | protected String testBasePackageDir; 39 | 40 | protected List clazzList; 41 | 42 | @Override 43 | public void init() throws IOException { 44 | projectDir = concat(Config.targetDir, Config.projectArtifactId); 45 | srcDir = concat(projectDir, "src"); 46 | 47 | mainDir = concat(srcDir, "main"); 48 | javaDir = concat(mainDir, "java"); 49 | resourcesDir = concat(mainDir, "resources"); 50 | webappDir = concat(mainDir, "webapp"); 51 | webInfDir = concat(webappDir, "WEB-INF"); 52 | basePackageDir = concat(javaDir, Config.projectPackage.split("\\.")); 53 | 54 | testDir = concat(srcDir, "test"); 55 | testJavaDir = concat(testDir, "java"); 56 | testResourcesDir = concat(testDir, "resources"); 57 | testBasePackageDir = concat(testJavaDir, Config.projectPackage.split("\\.")); 58 | 59 | //parse table to clazzs 60 | try { 61 | Parser parser = 62 | new MySQLParser(Config.mysqlJdbcUrl, Config.mysqlUsername, Config.mysqlPassword); 63 | clazzList = parser.parseDatabase(); 64 | } catch (Exception e) { 65 | log.error("parser error", e); 66 | } 67 | //clear target dir 68 | File file = new File(projectDir); 69 | if (file.exists()) { 70 | FileUtils.forceDelete(file); 71 | try { 72 | Thread.sleep(50); 73 | } catch (InterruptedException e) { 74 | } 75 | log.debug("clean dir: {}", projectDir); 76 | } 77 | } 78 | 79 | abstract void makeCustom() throws IOException, TemplateException; 80 | 81 | @Override 82 | public void generate() throws IOException, TemplateException { 83 | init(); 84 | base(); 85 | makeCustom(); 86 | } 87 | 88 | @Override 89 | public void base() throws IOException, TemplateException { 90 | GU.f(concat(projectDir, ".gitignore"), "gitIgnore"); 91 | GU.f(concat(projectDir, "pom.xml"), concat(Config.projectType, "pom")); 92 | generatorJava(); 93 | generatorTestJava(); 94 | } 95 | 96 | @Override 97 | public void clearIfFail() { 98 | try { 99 | FileUtils.forceDelete(new File(projectDir)); 100 | } catch (IOException e) { 101 | log.error("clearIfFail error", e); 102 | } 103 | } 104 | 105 | private void generatorJava() throws IOException, TemplateException { 106 | 107 | GU.f(concat(basePackageDir, "common", "BaseController.java"), "BaseController"); 108 | 109 | GU.f(concat(basePackageDir, "common", "BaseResponse.java"), "BaseResponse"); 110 | GU.f(concat(basePackageDir, "common", "BeanFactoryRegister.java"), "BeanFactoryRegister"); 111 | 112 | GU.f(concat(basePackageDir, "common", "exception", "BizException.java"), "BizException"); 113 | GU.f(concat(basePackageDir, "common", "exception", "GlobalExceptionHandler.java"), 114 | "GlobalExceptionHandler"); 115 | 116 | GU.f(concat(basePackageDir, "common", "interceptor", "ControllerInterceptor.java"), 117 | "ControllerInterceptor"); 118 | GU.f(concat(basePackageDir, "common", "interceptor", "HttpLog.java"), "HttpLog"); 119 | GU.f(concat(basePackageDir, "common", "interceptor", "HttpLogHolder.java"), 120 | "HttpLogHolder"); 121 | GU.f(concat(basePackageDir, "common", "interceptor", "LogResponseBodyAdvice.java"), 122 | "LogResponseBodyAdvice"); 123 | 124 | GU.f(concat(basePackageDir, "constant", "ErrorEnum.java"), "ErrorEnum"); 125 | 126 | GU.f(concat(basePackageDir, "utils", "ArithUtil.java"), "ArithUtil"); 127 | GU.f(concat(basePackageDir, "utils", "DateUtil.java"), "DateUtil"); 128 | 129 | GU.f(concat(basePackageDir, "web", "CommonController.java"), "CommonController"); 130 | 131 | GU.f(concat(basePackageDir, "web", "resp", ".gitkeep"), "gitkeep"); 132 | 133 | generatorByClazzList(); 134 | } 135 | 136 | private void generatorTestJava() throws IOException, TemplateException { 137 | GU.f(concat(testBasePackageDir, "common", "BeanFactoryRegisterTest.java"), 138 | "BeanFactoryRegisterTest"); 139 | 140 | GU.f(concat(testBasePackageDir, "utils", "ArithUtilTest.java"), "ArithUtilTest"); 141 | 142 | GU.f(concat(testBasePackageDir, "web", "CommonControllerTest.java"), 143 | "CommonControllerTest"); 144 | 145 | GU.f(concat(testBasePackageDir, "DBUtils.java"), "DBUtils"); 146 | GU.f(concat(testBasePackageDir, "AbstractTest.java"), 147 | concat(Config.projectType, "AbstractTest")); 148 | GU.f(concat(testBasePackageDir, "AbstractMVCTest.java"), 149 | concat(Config.projectType, "AbstractMVCTest")); 150 | } 151 | 152 | private void generatorByClazzList() throws IOException, TemplateException { 153 | for (Clazz clazz : clazzList) { 154 | Map data = new HashMap<>(); 155 | data.put("clazz", clazz); 156 | 157 | String mapperPath = 158 | concat(resourcesDir, "base", "mapper", clazz.getBclassName() + "-mapper.xml"); 159 | if (Config.projectType.indexOf("springboot") != -1) { 160 | mapperPath = concat(resourcesDir, "mapper", clazz.getBclassName() + "-mapper.xml"); 161 | } 162 | GU.f(mapperPath, concat("db", "mapperTemplate"), data); 163 | 164 | GU.f(concat(basePackageDir, "domain", clazz.getBclassName() + ".java"), 165 | concat("db", "entityTemplate"), data); 166 | GU.f(concat(basePackageDir, "dao", clazz.getBclassName() + "Dao.java"), 167 | concat("db", "daoTemplate"), data); 168 | GU.f(concat(basePackageDir, "service", clazz.getBclassName() + "Service.java"), 169 | concat("db", "serviceTemplate"), data); 170 | GU.f(concat(basePackageDir, "service", "impl", 171 | clazz.getBclassName() + "ServiceImpl.java"), concat("db", "serviceImplTemplate"), 172 | data); 173 | GU.f(concat(basePackageDir, "web", clazz.getBclassName() + "Controller.java"), 174 | concat("db", "controllerTemplate"), data); 175 | GU.f(concat(basePackageDir, "web", "req", 176 | "SaveOrUpdate" + clazz.getBclassName() + ".java"), 177 | concat("db", "saveOrUpdateReqTemplate"), data); 178 | 179 | GU.f(concat(testBasePackageDir, "dao", clazz.getBclassName() + "DaoTest.java"), 180 | concat("db", "daoTestTemplate"), data); 181 | 182 | GU.f(concat(testBasePackageDir, "data", clazz.getBclassName() + "Data.java"), 183 | concat("db", "dataTemplate"), data); 184 | 185 | GU.f(concat(testBasePackageDir, "service", "impl", 186 | clazz.getBclassName() + "ServiceImplTest.java"), 187 | concat(Config.projectType, "serviceImplTestTemplate"), data); 188 | 189 | GU.f(concat(testBasePackageDir, "web", clazz.getBclassName() + "ControllerTest.java"), 190 | concat("db", "controllerTestTemplate"), data); 191 | } 192 | } 193 | 194 | protected static String concat(String baseName, String... appendName) { 195 | if (appendName.length == 0) { 196 | return baseName; 197 | } else { 198 | StringBuilder concatName = new StringBuilder(); 199 | if (baseName.endsWith(File.separator)) { 200 | concatName.append(baseName).append(appendName[0]); 201 | } else { 202 | concatName.append(baseName).append(File.separator).append(appendName[0]); 203 | } 204 | if (appendName.length > 1) { 205 | for (int i = 1; i < appendName.length; ++i) { 206 | concatName.append(File.separator).append(appendName[i]); 207 | } 208 | } 209 | 210 | return concatName.toString(); 211 | } 212 | } 213 | 214 | } 215 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/generator/impl/BootPageGenerator.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker.generator.impl; 2 | 3 | /** 4 | * springboot-page生成器 5 | */ 6 | public class BootPageGenerator extends BaseGenerator { 7 | 8 | @Override 9 | public void makeCustom() { 10 | //not implement 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/generator/impl/BootRestGenerator.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker.generator.impl; 2 | 3 | import com.flyer.maker.base.Config; 4 | import com.flyer.maker.utils.GU; 5 | import freemarker.template.TemplateException; 6 | 7 | import java.io.IOException; 8 | 9 | /** 10 | * springboot-rest生成器 11 | */ 12 | public class BootRestGenerator extends BaseGenerator { 13 | 14 | @Override 15 | public void makeCustom() throws IOException, TemplateException { 16 | GU.f(concat(basePackageDir, "App.java"), concat(Config.projectType, "App.java")); 17 | GU.f(concat(basePackageDir, "common", "WebMvcConfig.java"), 18 | concat(Config.projectType, "WebMvcConfig")); 19 | generatorResources(); 20 | generatorTestResources(); 21 | } 22 | 23 | private void generatorTestResources() throws IOException, TemplateException { 24 | GU.f(concat(testResourcesDir, "application.properties"), 25 | concat(Config.projectType, "unit_application.properties")); 26 | GU.f(concat(testResourcesDir, "logback-test.xml"), 27 | concat(Config.projectType, "logback-test")); 28 | } 29 | 30 | private void generatorResources() throws IOException, TemplateException { 31 | GU.f(concat(resourcesDir, "application.properties"), 32 | concat(Config.projectType, "application.properties")); 33 | GU.f(concat(resourcesDir, "application-dev.properties"), 34 | concat(Config.projectType, "application-dev.properties")); 35 | GU.f(concat(resourcesDir, "application-prod.properties"), 36 | concat(Config.projectType, "application-prod.properties")); 37 | GU.f(concat(resourcesDir, "application-stage.properties"), 38 | concat(Config.projectType, "application-stage.properties")); 39 | GU.f(concat(resourcesDir, "application-test.properties"), 40 | concat(Config.projectType, "application-test.properties")); 41 | GU.f(concat(resourcesDir, "logback-spring.xml"), 42 | concat(Config.projectType, "logback-spring")); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/generator/impl/MvcPageGenerator.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker.generator.impl; 2 | 3 | /** 4 | * springmvc-page生成器 5 | */ 6 | public class MvcPageGenerator extends BaseGenerator { 7 | 8 | @Override 9 | public void makeCustom() { 10 | //not implement 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/generator/impl/MvcRestGenerator.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker.generator.impl; 2 | 3 | import com.flyer.maker.base.Config; 4 | import com.flyer.maker.utils.GU; 5 | import freemarker.template.TemplateException; 6 | 7 | import java.io.IOException; 8 | 9 | /** 10 | * springbmvc-rest生成器 11 | */ 12 | public class MvcRestGenerator extends BaseGenerator { 13 | 14 | @Override 15 | public void makeCustom() throws IOException, TemplateException { 16 | GU.f(concat(basePackageDir, "common", "listener", "LogbackProfileListener.java"), 17 | "LogbackProfileListener"); 18 | generatorResources(); 19 | generatorTestResources(); 20 | GU.f(concat(webInfDir, "web.xml"), concat(Config.projectType, "webxml")); 21 | GU.f(concat(webInfDir, "spring-servlet.xml"), concat(Config.projectType, "spring-servlet")); 22 | } 23 | 24 | private void generatorResources() throws IOException, TemplateException { 25 | GU.f(concat(resourcesDir, "base", "spring-bootstrap.xml"), 26 | concat(Config.projectType, "spring-bootstrap")); 27 | GU.f(concat(resourcesDir, "base", "spring-core.xml"), 28 | concat(Config.projectType, "spring-core")); 29 | GU.f(concat(resourcesDir, "base", "spring-dao.xml"), 30 | concat(Config.projectType, "spring-dao")); 31 | GU.f(concat(resourcesDir, "base", "spring-profile.xml"), 32 | concat(Config.projectType, "spring-profile")); 33 | 34 | GU.f(concat(resourcesDir, "dev", "config.properties"), 35 | concat(Config.projectType, "dev_config.properties")); 36 | GU.f(concat(resourcesDir, "dev", "logback.xml"), concat(Config.projectType, "dev_logback")); 37 | 38 | GU.f(concat(resourcesDir, "test", "config.properties"), 39 | concat(Config.projectType, "test_config.properties")); 40 | GU.f(concat(resourcesDir, "test", "logback.xml"), 41 | concat(Config.projectType, "test_logback")); 42 | 43 | GU.f(concat(resourcesDir, "stage", "config.properties"), 44 | concat(Config.projectType, "stage_config.properties")); 45 | GU.f(concat(resourcesDir, "stage", "logback.xml"), 46 | concat(Config.projectType, "stage_logback")); 47 | 48 | GU.f(concat(resourcesDir, "prod", "config.properties"), 49 | concat(Config.projectType, "prod_config.properties")); 50 | GU.f(concat(resourcesDir, "prod", "logback.xml"), 51 | concat(Config.projectType, "prod_logback")); 52 | } 53 | 54 | private void generatorTestResources() throws IOException, TemplateException { 55 | GU.f(concat(testResourcesDir, "config.properties"), 56 | concat(Config.projectType, "unit_config.properties")); 57 | GU.f(concat(testResourcesDir, "logback-test.xml"), 58 | concat(Config.projectType, "logback-test")); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/parser/Parser.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker.parser; 2 | 3 | import com.flyer.maker.base.Clazz; 4 | 5 | import java.sql.SQLException; 6 | import java.util.List; 7 | 8 | /** 9 | * parser 10 | */ 11 | public interface Parser { 12 | 13 | List parseDatabase() throws SQLException; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/parser/impl/MySQLParser.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker.parser.impl; 2 | 3 | import com.flyer.maker.base.Clazz; 4 | import com.flyer.maker.base.Config; 5 | import com.flyer.maker.base.Field; 6 | import com.flyer.maker.parser.Parser; 7 | import com.flyer.maker.utils.DBUtil; 8 | import com.flyer.maker.utils.FormatUtil; 9 | import org.apache.commons.lang3.StringUtils; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | import java.sql.Connection; 14 | import java.sql.ResultSet; 15 | import java.sql.SQLException; 16 | import java.sql.Statement; 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | 20 | /** 21 | * MySQL parser 22 | */ 23 | public class MySQLParser implements Parser { 24 | 25 | private final Logger log = LoggerFactory.getLogger(MySQLParser.class); 26 | 27 | private final static String driverClass = "com.mysql.jdbc.Driver"; 28 | 29 | private Connection connection; 30 | 31 | public MySQLParser(String url, String user, String password) 32 | throws SQLException, ClassNotFoundException { 33 | connection = DBUtil.getConnection(driverClass, url, user, password); 34 | } 35 | 36 | @Override 37 | public List parseDatabase() throws SQLException { 38 | String database = connection.getCatalog(); 39 | if (StringUtils.isBlank(database)) { 40 | throw new RuntimeException("please assign the db in db url"); 41 | } 42 | Statement stmt = connection.createStatement(); 43 | String tsql = 44 | "select table_name ,table_comment from information_schema.tables where table_schema = '" 45 | + database + "'"; 46 | ResultSet rs = stmt.executeQuery(tsql); 47 | List clazzList = new ArrayList(); 48 | String tableName; 49 | while (rs.next()) { 50 | tableName = rs.getString(1).toLowerCase(); 51 | //白名单、黑名单过滤 52 | if (!Config.tableIncludeList.isEmpty()) { 53 | if (!Config.tableIncludeList.contains(tableName)) { 54 | continue; 55 | } 56 | } else { 57 | if (!Config.tableExcludeList.isEmpty()) { 58 | if (Config.tableExcludeList.contains(tableName)) { 59 | continue; 60 | } 61 | } 62 | } 63 | Clazz clazz = new Clazz(); 64 | clazz.setTableName(tableName); 65 | clazz.setClassName(FormatUtil.formatClassName(tableName)); 66 | clazz.setBclassName(FormatUtil.formatBClassName(tableName)); 67 | clazz.setResouceName(FormatUtil.formatResource(tableName)); 68 | clazz.setDesc(rs.getString(2)); 69 | List fieldList = getField(database, tableName); 70 | clazzList.add(builder(clazz, fieldList)); 71 | } 72 | DBUtil.closeConnection(connection); 73 | return clazzList; 74 | } 75 | 76 | private List getField(String database, String tableName) throws SQLException { 77 | String sql = 78 | ("select column_name,data_type,column_comment,character_maximum_length,extra from information_schema.columns where table_name = '" 79 | + tableName + "'" + " and table_schema = '" + database + "'"); 80 | Statement stmt = connection.createStatement(); 81 | ResultSet rs = stmt.executeQuery(sql); 82 | List filedList = new ArrayList<>(); 83 | while (rs.next()) { 84 | String columnName = rs.getString(1); 85 | if (Config.columnExcludeList.contains(columnName)) { 86 | continue; 87 | } 88 | Field filed = new Field(); 89 | filed.setTname(columnName.toLowerCase()); 90 | filed.setBname(FormatUtil.formatBField(columnName)); 91 | filed.setName(FormatUtil.formatField(columnName)); 92 | filed.setClassType(convertClass(rs.getString(2).toLowerCase())); 93 | filed.setDesc(rs.getString(3).toLowerCase()); 94 | 95 | long len = 3; 96 | try { 97 | len = calMaxRandomLen(rs); 98 | } catch (Exception e) { 99 | log.error("table : {}, columnName : {} calMaxRandomLen error", tableName, 100 | columnName); 101 | } 102 | filed.setMaxRandomLen((int)len); 103 | filed.setExtra(rs.getString(5).toLowerCase()); 104 | filedList.add(filed); 105 | } 106 | return filedList; 107 | } 108 | 109 | private Clazz builder(Clazz clazz, List fieldList) { 110 | List insertfiledList = new ArrayList(); 111 | List classfiledList = new ArrayList(); 112 | for (Field field : fieldList) { 113 | if (field.getTname().equals("id") || field.getExtra().equalsIgnoreCase("auto_increment")) { 114 | clazz.setIdType(field.getClassType()); 115 | clazz.setIdTypeSimple( 116 | "Integer".equals(field.getClassType()) ? "Int" : field.getClassType()); 117 | } else { 118 | insertfiledList.add(field); 119 | } 120 | classfiledList.add(field); 121 | } 122 | clazz.setTablefieldList(fieldList); 123 | clazz.setInsertfieldList(insertfiledList); 124 | clazz.setFieldList(classfiledList); 125 | return clazz; 126 | } 127 | 128 | public String convertClass(String fieldType) { 129 | if (fieldType.contains("char")) 130 | fieldType = "String"; 131 | else if (fieldType.contains("bigint")) 132 | fieldType = "Long"; 133 | else if (fieldType.contains("int")) 134 | fieldType = "Integer"; 135 | else if (fieldType.contains("float")) 136 | fieldType = "Float"; 137 | else if (fieldType.contains("double")) 138 | fieldType = "Double"; 139 | else if (fieldType.contains("number")) 140 | fieldType = "java.math.BigDecimal"; 141 | else if (fieldType.contains("decimal")) 142 | fieldType = "java.math.BigDecimal"; 143 | else if (fieldType.contains("date")) 144 | fieldType = "java.util.Date"; 145 | else if (fieldType.contains("time")) 146 | fieldType = "java.sql.Timestamp"; 147 | else if (fieldType.contains("blob")) 148 | fieldType = "byte[]"; 149 | else 150 | fieldType = "String"; 151 | return fieldType; 152 | } 153 | 154 | private long calMaxRandomLen(ResultSet rs) throws SQLException { 155 | long maxLen = 0; 156 | String fieldMaxLen = rs.getString(4); 157 | if (StringUtils.isNotBlank(fieldMaxLen)) { 158 | maxLen = Long.parseLong(fieldMaxLen) - rs.getString(1).length() - 1; 159 | if (maxLen > 0 && maxLen >= 20) { 160 | maxLen = 20; 161 | } 162 | if (maxLen < 0) { 163 | maxLen = -Integer.parseInt(fieldMaxLen); 164 | if (maxLen < -20) { 165 | maxLen = -20; 166 | } 167 | } 168 | } 169 | return maxLen; 170 | } 171 | 172 | } 173 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/utils/DBUtil.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker.utils; 2 | 3 | import java.sql.Connection; 4 | import java.sql.DriverManager; 5 | import java.sql.SQLException; 6 | 7 | /** 8 | * db util 9 | */ 10 | public class DBUtil { 11 | 12 | public static Connection getConnection(String driverClass, String url, String user, 13 | String password) throws SQLException, ClassNotFoundException { 14 | Class.forName(driverClass); 15 | return DriverManager.getConnection(url, user, password); 16 | } 17 | 18 | public static void closeConnection(Connection connection) throws SQLException { 19 | if (connection != null) { 20 | connection.close(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/utils/FormatUtil.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker.utils; 2 | 3 | /** 4 | * 字符串格式化工具 5 | */ 6 | public class FormatUtil { 7 | 8 | /** 9 | * 去除下划线,并大写下划线右边首字母(第一个字母小写) 10 | */ 11 | public static String formatField(String field) { 12 | field = field.toLowerCase(); 13 | String[] strs = field.split("_"); 14 | field = strs[0]; 15 | for (int i = 1; i < strs.length; i++) { 16 | String tempStr = strs[i].toLowerCase(); 17 | tempStr = 18 | tempStr.substring(0, 1).toUpperCase() + tempStr.substring(1, tempStr.length()); 19 | field = field + tempStr; 20 | } 21 | return field; 22 | } 23 | 24 | public static String formatBField(String field) { 25 | field = formatField(field); 26 | field = field.substring(0, 1).toUpperCase() + field.substring(1, field.length()); 27 | return field; 28 | } 29 | 30 | /** 31 | * user_money ->userMoney 32 | */ 33 | public static String formatClassName(String tableName) { 34 | tableName = tableName.toLowerCase(); 35 | return formatField(tableName); 36 | } 37 | 38 | /** 39 | * user_money -> UserMoney 40 | */ 41 | public static String formatBClassName(String tableName) { 42 | tableName = formatResource(tableName); 43 | tableName = formatField(tableName); 44 | tableName = 45 | tableName.substring(0, 1).toUpperCase() + tableName.substring(1, tableName.length()); 46 | return tableName; 47 | } 48 | 49 | public static String formatResource(String tableName) { 50 | tableName = tableName.toLowerCase(); 51 | return tableName; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/flyer/maker/utils/GU.java: -------------------------------------------------------------------------------- 1 | package com.flyer.maker.utils; 2 | 3 | import com.flyer.maker.freemarker.FreemarkerConfig; 4 | import freemarker.template.Template; 5 | import freemarker.template.TemplateException; 6 | import org.apache.commons.io.FileUtils; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.io.*; 12 | import java.util.Map; 13 | 14 | /** 15 | * Generator Utils 16 | */ 17 | public class GU { 18 | 19 | private final static Logger log = LoggerFactory.getLogger(GU.class); 20 | 21 | /** 22 | * create a dir 23 | * 24 | * @param path 25 | */ 26 | public static void d(String path) { 27 | if (StringUtils.isNotBlank(path)) { 28 | try { 29 | FileUtils.forceMkdir(new File(path)); 30 | } catch (IOException e) { 31 | log.error("create dir {} error", path, e); 32 | } 33 | log.debug("create dir {}", path); 34 | } 35 | } 36 | 37 | /** 38 | * create more than one dir 39 | * 40 | * @param paths 41 | */ 42 | public static void d(String... paths) { 43 | if (paths != null) { 44 | for (String path : paths) { 45 | d(path); 46 | } 47 | } 48 | } 49 | 50 | /** 51 | * generate file with freemarker template file 52 | * @param file target file path 53 | * @param templeteFile 54 | */ 55 | public static void f(String file, String templeteFile) throws IOException, TemplateException { 56 | f(file, templeteFile, null); 57 | } 58 | 59 | /** 60 | * generate file with freemarker template file 61 | * @param file target file path 62 | * @param templeteFile freemarker template file 63 | * @param data 64 | */ 65 | public static void f(String file, String templeteFile, Map data) 66 | throws IOException, TemplateException { 67 | generateFile(templeteFile, file, data); 68 | } 69 | 70 | private static void generateFile(String templateFileName, String fileNamePath, 71 | Map data) throws IOException, TemplateException { 72 | FileUtils.forceMkdir(new File(fileNamePath).getParentFile()); 73 | Template template = FreemarkerConfig.getConfiguration().getTemplate(templateFileName + ".ftl"); 74 | Writer out = new OutputStreamWriter(new FileOutputStream(fileNamePath), "UTF-8"); 75 | template.process(data, out); 76 | out.close(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | ## 作者,可选,默认值 'flyermaker' 2 | author= 3 | 4 | ## 设置目标目录,可选,默认值为 当前目录 5 | target.dir= 6 | 7 | ## 工程类型,必填,springmvc-rest,springboot-rest,springmvc-page,springboot-page 8 | project.type=springboot-rest 9 | 10 | ## Maven groupId,必填 11 | project.groupId=com.flyer 12 | 13 | ## Maven artifactId,必填 14 | project.artifactId=flyer-springmvc-rest 15 | 16 | ## base package,必填 17 | project.package=com.flyer.springmvc.rest 18 | 19 | ## 目前只支持MySQL,必填 20 | mysql.jdbc.url=jdbc:mysql://localhost:3306/flyer?useUnicode=true&characterEncoding=utf-8&useSSL=false 21 | 22 | ## username of mysql,必填 23 | mysql.username=flyer_w 24 | 25 | ## password of mysql,必填 26 | mysql.password=123456 27 | 28 | ## 数据库表白名单,非必填 29 | mysql.table.include= 30 | 31 | ## 数据库表黑名单,非必填 32 | mysql.table.exclude= 33 | 34 | ## 字段黑名单,非必填 35 | mysql.column.exclude= 36 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %d{HH:mm:ss.SSS} %-5level %msg%n 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | --------------------------------------------------------------------------------