diff --git a/README.md b/README.md index 10f1ecfc..e745f5f0 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,75 @@ +# SpringBootCodeGenerator ![image](https://img.shields.io/badge/SpringBoot2-%E2%98%85%E2%98%85%E2%98%85%E2%98%85%E2%98%85-brightgreen.svg) ![image](https://img.shields.io/badge/Freemarker-%E2%98%85%E2%98%85%E2%98%85%E2%98%85%E2%98%85-brightgreen.svg) ![image](https://img.shields.io/badge/CodeGenerator-%E2%98%85%E2%98%85%E2%98%85%E2%98%85%E2%98%85-brightgreen.svg) [![Build Status](https://travis-ci.org/moshowgame/SpringBootCodeGenerator.svg?branch=master)](https://travis-ci.org/moshowgame/SpringBootCodeGenerator) -
-SpringBootCodeGenerator ----- -√基于SpringBoot2+Freemarker的代码生成器,√以释放双手为目的,√支持mysql/oracle/pgsql三大数据库,
-√用DDL-SQL语句生成JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL相关代码。

-另外,感谢bejson三叔将他部署在 http://java.bejson.com/generator 上,目前是besjon专供工具(线上版本不一定是最新的,会有延迟,请谅解,谢谢)。 -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
访问路径 http://127.0.0.1:1234/generator
在线地址 http://java.bejson.com/generator
CSDN博客 http://zhengkai.blog.csdn.net
更新日期 更新内容
201911151.添加tinyint类型转换(感谢@lixiliang&@liujiansgit的Suggestion) 2.添加一键复制功能(感谢@gaohanghang的Suggestion) 3.Mybatis的insert增加keyProperty="id"用于返回自增id(感谢@88888888888888888888的Suggestion) 4.优化date类型的支持(感谢@SteveLsf的反馈) 5.其他一些优化.
20191015修复jdbcTemplates中insert语句第一个字段丢失的问题。
201909151.添加对象getset模板 2.添加sql模板 3.启动类添加日志输出,方便项目使用(感谢@gaohanghang 的pull request)
20190910-2优化以及更新Maven依赖,减少打包体积。
20190910-11.修复mapper接口load方法,但是xml中方法不匹配问题 2.移除mapper中CRUD时的@param 注解,会影响xml的解析(感谢@caojiantao的反馈)。3.优化MyBatis的xml文件对Oracle的支持。(感谢@wylove1992的反馈) 4.新增对boolean的处理(感谢@violinxsc的反馈)以及优化tinyint类型生成boolean类型问题(感谢@hahaYhui的反馈)
20190909添加是否下划线转换为驼峰的选择(感谢@youngking28 的pull request)。
201905181.优化注释 2.修改 mybatis模板中 controller注解 3.修改 mybatis模板中 dao文件使用为 mapper文件 4.修改 mybatis模板中 service实现类中的一个 bug 5.修改 index.ftl文件中 mybatis模板的 dao -> mapper(感谢@unqin的pull request)
20190511优化mybatis模块的dao和xml模板,修改dao接口注解为@Repository,所有dao参数改为包装类,删除update语句最后的UpdateTime = NOW(),修改dao接口文件的方法注释使其更符合javaDoc的标准,修改insert语句增加插入行主键的返回,修改load的方法名为selectByPrimaryKey,修改xml的update语句新增动态if判空,修改xml的insert语句新增动态插入判空,更符合mybatisGenerator标准(感谢@Archer-Wen的贡献 )。
20190429新增返回封装工具类设置,优化对oracle注释comment on column的支持(感谢@liukex反馈),优化对普通和特殊storage关键字的判断(感谢@AhHeadFloating的反馈 )。
20190211提交gitignore,解决StringUtils.lowerCaseFirst潜在的NPE异常,校验修改为@RequestParam参数校验,lombok之@Data和@Slf4j优化,fix JdbcDAO模板类名显示为中文问题,WebMvcConfig整合MessageConverter,模板代码分类(感谢@liutf和@tfgzs的pull request)。
20190210实体生成规则切换为包装类型,不再采用基本数据类型,为实体类生成添加显示的默认构造方法(感谢@h2so的pull request)。
20190106修复处理number/decimal(x,x)类型的逻辑(感谢@arthaschan的反馈),修复JdbcTemplates模板两处错误(感谢@everflourish的反馈)。
20181212首页UI优化,新增MybatisPlus模块(感谢@三叔同事的建议),修复作者名和包名获取失败问题(感谢@Yanch1994的反馈)。
20181122优化正则表达式点号的处理,优化处理字段类型,对number类型增加int,long,BigDecimal的区分判断(感谢@lshz0088的指导)。
20181108修复非字段描述"KEY FK_xxxx (xxxx)"导致生成KEY字段情况(感谢@tornadoorz反馈)。
20181018支持double(x,x)的类型,以及comment里面包含一些特殊字符的处理(感谢@tanwubo的反馈)。
20181010CDN变更,修复CDN不稳定导致网页js报错问题。
20181003新增element-ui/bootstrap生成。
20181002修复公共CDN之Layer.js404问题,导致项目无法生成。
20180927优化COMMENT提取逻辑,支持多种复杂情况的注释(感谢@raodeming的反馈)。
20180926全新BeetlSQL模块,以及一些小细节优化(感谢@三叔同事的建议)。
20180925优化SQL表和字段备注的推断,包括pgsql/oralce的comment on column/table情况处理等。
20180918优化SQL类型推断。优化PrimaryKey判断。修复jpacontroller中Repository拼写错误问题。
20180917全新首页,静态文件全部采用CDN。新增jdbcTemplate模块。
20180916-2优化oracle支持,优化DDL语句中"或者'或者空格的支持。
20180916-1补充char/clob/blob/json等类型,如果类型未知,默认为String。
20180915新增Swagger-UI模板。修复一些命名和导入问题。JPA的Entity默认第一个字段为Id,如果不是请手工修改。
20180913修复字段没有描述以及类型为DATE型导致的问题。新增JPA的Controller模板。
20180831初始化项目。新增JPA系列Entity+Repository模板。
- - - - - - - - - - -
字段名 说明
packageName 自定义的包名
authorName 自定义的作者名
returnUtil 自定义的返回Util
tableName sql中的表名
className java类名
classComment sql表备注/java类备注
fieldName 字段名
fieldComment 字段备注
+# Description +- √ 基于SpringBoot2+Freemarker+Bootstrap +- √ 以释放双手为目的 +- √ 支持mysql/oracle/pgsql三大数据库 +- √ 用DDL-SQL语句生成JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL相关代码. + + +# Url + +|访问路径|http://localhost:1234/generator| +|-|-| +|在线地址|http://java.bejson.com/generator| +|CSDN博客|http://zhengkai.blog.csdn.net| + +感谢bejson三叔将他部署在[BEJSON](www.bejson.com)上,目前是besjon专供工具(线上版本不一定是最新的,会有延迟,请谅解,谢谢). + + +# Update + +|更新日期|更新内容| +|-|-| +|20191124|1.java代码结构优化. 2.新增简单的json生成模式 3.新增简单的正则表达式匹配模式(感谢@ydq的贡献) 4.新增对复制String代码中的乱SQL代码的支持 5.优化对JSON的父子节点/处理,JSONObject和JSONArray节点处理,子节点缺失'{'头处理| +|20191123|1.移除频繁出错和被过滤的layer,改为jquery-toast. 2.Util功能优化,新增json和xml.| +|20191116|优化对primary关键字的处理(感谢@liujiansgit的反馈). | +|20191115|1.添加tinyint类型转换(感谢@lixiliang&@liujiansgit的Suggestion) 2.添加一键复制功能(感谢@gaohanghang的Suggestion) 3.Mybatis的insert增加keyProperty="id"用于返回自增id(感谢@88888888888888888888的Suggestion) 4.优化date类型的支持(感谢@SteveLsf的反馈) 5.其他一些优化. | +|20191015|修复jdbcTemplates中insert语句第一个字段丢失的问题. | +|20190915|1.添加对象getset模板 2.添加sql模板 3.启动类添加日志输出,方便项目使用(感谢@gaohanghang 的pull request) | +|20190910-2|优化以及更新Maven依赖,减少打包体积. | +|20190910-1|1.修复mapper接口load方法,但是xml中方法不匹配问题 2.移除mapper中CRUD时的@param 注解,会影响xml的解析(感谢@caojiantao的反馈).3.优化MyBatis的xml文件对Oracle的支持.(感谢@wylove1992的反馈) 4.新增对boolean的处理(感谢@violinxsc的反馈)以及优化tinyint类型生成boolean类型问题(感谢@hahaYhui的反馈) | +|20190909|添加是否下划线转换为驼峰的选择(感谢@youngking28 的pull request).| +|20190518|1.优化注释 2.修改 mybatis模板中 controller注解 3.修改 mybatis模板中 dao文件使用为 mapper文件 4.修改 mybatis模板中 service实现类中的一个 bug 5.修改 index.ftl文件中 mybatis模板的 dao -> mapper(感谢@unqin的pull request)| +|20190511|优化mybatis模块的dao和xml模板,修改dao接口注解为@Repository,所有dao参数改为包装类,删除update语句最后的UpdateTime = NOW(),修改dao接口文件的方法注释使其更符合javaDoc的标准,修改insert语句增加插入行主键的返回,修改load的方法名为selectByPrimaryKey,修改xml的update语句新增动态if判空,修改xml的insert语句新增动态插入判空,更符合mybatisGenerator标准(感谢@Archer-Wen的贡献 ).| +|20190429|新增返回封装工具类设置,优化对oracle注释comment on column的支持(感谢@liukex反馈),优化对普通和特殊storage关键字的判断(感谢@AhHeadFloating的反馈 ).| +|20190211|提交gitignore,解决StringUtils.lowerCaseFirst潜在的NPE异常,校验修改为@RequestParam参数校验,lombok之@Data和@Slf4j优化,fix JdbcDAO模板类名显示为中文问题,WebMvcConfig整合MessageConverter,模板代码分类(感谢@liutf和@tfgzs的pull request).| +|20190210|实体生成规则切换为包装类型,不再采用基本数据类型,为实体类生成添加显示的默认构造方法(感谢@h2so的pull request).| +|20190106|修复处理number/decimal(x,x)类型的逻辑(感谢@arthaschan的反馈),修复JdbcTemplates模板两处错误(感谢@everflourish的反馈).| +|20181212|首页UI优化,新增MybatisPlus模块(感谢@三叔同事的建议),修复作者名和包名获取失败问题(感谢@Yanch1994的反馈).| +|20181122|优化正则表达式点号的处理,优化处理字段类型,对number类型增加int,long,BigDecimal的区分判断(感谢@lshz0088的指导).| +|20181108|修复非字段描述"KEY FK_xxxx (xxxx)"导致生成KEY字段情况(感谢@tornadoorz反馈).| +|20181018|支持double(x,x)的类型,以及comment里面包含一些特殊字符的处理(感谢@tanwubo的反馈).| +|20181010|CDN变更,修复CDN不稳定导致网页js报错问题.| +|20181003|新增element-ui/bootstrap生成.| +|20181002|修复公共CDN之Layer.js404问题,导致项目无法生成.| +|20180927|优化COMMENT提取逻辑,支持多种复杂情况的注释(感谢@raodeming的反馈).| +|20180926|全新BeetlSQL模块,以及一些小细节优化(感谢@三叔同事的建议).| +|20180925|优化SQL表和字段备注的推断,包括pgsql/oralce的comment on column/table情况处理等.| +|20180918|优化SQL类型推断.优化PrimaryKey判断.修复jpacontroller中Repository拼写错误问题.| +|20180917|全新首页,静态文件全部采用CDN.新增jdbcTemplate模块.| +|20180916|1.优化oracle支持,优化DDL语句中"或者'或者空格的支持. 2.补充char/clob/blob/json等类型,如果类型未知,默认为String.| +|20180915|新增Swagger-UI模板.修复一些命名和导入问题.JPA的Entity默认第一个字段为Id,如果不是请手工修改.| +|20180913|修复字段没有描述以及类型为DATE型导致的问题.新增JPA的Controller模板.| +|20180831|初始化项目.新增JPA系列Entity+Repository模板.| + +# FieldName +|字段名|说明| +|-|-| +|packageName|自定义的包名| +|authorName|自定义的作者名| +|returnUtil|自定义的返回Util| +|tableName|sql中的表名| +|className|java类名| +|classComment|sql表备注/java类备注| +|fieldName|字段名| +|fieldComment|字段备注| + diff --git a/donate.jpg b/donate.jpg index d8202fce..08c3a13e 100644 Binary files a/donate.jpg and b/donate.jpg differ diff --git a/generator-web/src/main/java/com/softdev/system/generator/config/GlobalDefaultExceptionHandler.java b/generator-web/src/main/java/com/softdev/system/generator/config/GlobalDefaultExceptionHandler.java index ece439c0..1ab40039 100644 --- a/generator-web/src/main/java/com/softdev/system/generator/config/GlobalDefaultExceptionHandler.java +++ b/generator-web/src/main/java/com/softdev/system/generator/config/GlobalDefaultExceptionHandler.java @@ -2,22 +2,19 @@ import javax.servlet.http.HttpServletRequest; +import com.softdev.system.generator.entity.ReturnT; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; -import com.softdev.system.generator.util.ApiReturnObject; -import com.softdev.system.generator.util.ApiReturnUtil; - @ControllerAdvice public class GlobalDefaultExceptionHandler { @ExceptionHandler(Exception.class) @ResponseBody - public ApiReturnObject defaultExceptionHandler(HttpServletRequest req,Exception e) { + public ReturnT defaultExceptionHandler(HttpServletRequest req,Exception e) { e.printStackTrace(); - //return new ApiReturnObject("01","server error", e.getMessage()); - return ApiReturnUtil.error("服务器异常",e.getMessage()); + return new ReturnT<>(ReturnT.FAIL_CODE, e.getMessage()); } } diff --git a/generator-web/src/main/java/com/softdev/system/generator/controller/IndexController.java b/generator-web/src/main/java/com/softdev/system/generator/controller/IndexController.java index ce0e79c6..4df4b894 100644 --- a/generator-web/src/main/java/com/softdev/system/generator/controller/IndexController.java +++ b/generator-web/src/main/java/com/softdev/system/generator/controller/IndexController.java @@ -1,7 +1,10 @@ package com.softdev.system.generator.controller; import com.softdev.system.generator.entity.ClassInfo; +import com.softdev.system.generator.entity.ParamInfo; import com.softdev.system.generator.entity.ReturnT; +import com.softdev.system.generator.service.GeneratorService; +import com.softdev.system.generator.util.CodeGenerateException; import com.softdev.system.generator.util.FreemarkerTool; import com.softdev.system.generator.util.TableParseUtil; import freemarker.template.TemplateException; @@ -9,9 +12,7 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.*; import java.io.IOException; import java.util.HashMap; @@ -26,92 +27,51 @@ public class IndexController { @Autowired - private FreemarkerTool freemarkerTool; + private GeneratorService generatorService; - @RequestMapping("/") + @GetMapping("/") public String index() { return "index"; } - @RequestMapping("/genCode") + @PostMapping("/genCode") @ResponseBody - public ReturnT> codeGenerate(String tableSql, - //2019-2-10 liutf 修改为@RequestParam参数校验 - @RequestParam(required = false, defaultValue = "大狼狗") String authorName, - @RequestParam(required = false, defaultValue = "com.softdev.system")String packageName, - @RequestParam(required = false, defaultValue = "ApiReturnUtil")String returnUtil, - @RequestParam(required = false, defaultValue = "true")boolean isUnderLineToCamelCase, - @RequestParam(required = false, defaultValue = "boolean")String tinyintTransType - ) { - + public ReturnT> codeGenerate( ParamInfo paramInfo ) { try { - if (StringUtils.isBlank(tableSql)) { + if (StringUtils.isBlank(paramInfo.getTableSql())) { return new ReturnT<>(ReturnT.FAIL_CODE, "表结构信息不可为空"); } // parse table - ClassInfo classInfo = TableParseUtil.processTableIntoClassInfo(tableSql, isUnderLineToCamelCase, tinyintTransType); + ClassInfo classInfo = null; + switch (paramInfo.getDataType()){ + //parse json + case "json":classInfo = TableParseUtil.processJsonToClassInfo(paramInfo);break; + //parse sql by regex + case "sql-regex":classInfo = TableParseUtil.processTableToClassInfoByRegex(paramInfo);break; + //default parse sql by java + default : classInfo = TableParseUtil.processTableIntoClassInfo(paramInfo);break; + } - // code genarete + // process the param Map params = new HashMap(8); params.put("classInfo", classInfo); - params.put("authorName", authorName); - params.put("packageName", packageName); - params.put("returnUtil", returnUtil); - - // result - Map result = new HashMap(32); + params.put("authorName", paramInfo.getAuthorName()); + params.put("packageName", paramInfo.getPackageName()); + params.put("returnUtil", paramInfo.getReturnUtil()); - //UI - result.put("swagger-ui", freemarkerTool.processString("code-generator/ui/swagger-ui.ftl", params)); - result.put("element-ui", freemarkerTool.processString("code-generator/ui/element-ui.ftl", params)); - result.put("bootstrap-ui", freemarkerTool.processString("code-generator/ui/bootstrap-ui.ftl", params)); - //mybatis old - result.put("controller", freemarkerTool.processString("code-generator/mybatis/controller.ftl", params)); - result.put("service", freemarkerTool.processString("code-generator/mybatis/service.ftl", params)); - result.put("service_impl", freemarkerTool.processString("code-generator/mybatis/service_impl.ftl", params)); - result.put("mapper", freemarkerTool.processString("code-generator/mybatis/mapper.ftl", params)); - result.put("mybatis", freemarkerTool.processString("code-generator/mybatis/mybatis.ftl", params)); - result.put("model", freemarkerTool.processString("code-generator/mybatis/model.ftl", params)); - //jpa - result.put("entity", freemarkerTool.processString("code-generator/jpa/entity.ftl", params)); - result.put("repository", freemarkerTool.processString("code-generator/jpa/repository.ftl", params)); - result.put("jpacontroller", freemarkerTool.processString("code-generator/jpa/jpacontroller.ftl", params)); - //jdbc template - result.put("jtdao", freemarkerTool.processString("code-generator/jdbc-template/jtdao.ftl", params)); - result.put("jtdaoimpl", freemarkerTool.processString("code-generator/jdbc-template/jtdaoimpl.ftl", params)); - //beetsql - result.put("beetlmd", freemarkerTool.processString("code-generator/beetlsql/beetlmd.ftl", params)); - result.put("beetlentity", freemarkerTool.processString("code-generator/beetlsql/beetlentity.ftl", params)); - result.put("beetlentitydto", freemarkerTool.processString("code-generator/beetlsql/beetlentitydto.ftl", params)); - result.put("beetlcontroller", freemarkerTool.processString("code-generator/beetlsql/beetlcontroller.ftl", params)); - //mybatis plus - result.put("pluscontroller", freemarkerTool.processString("code-generator/mybatis-plus/pluscontroller.ftl", params)); - result.put("plusmapper", freemarkerTool.processString("code-generator/mybatis-plus/plusmapper.ftl", params)); - //util - result.put("util", freemarkerTool.processString("code-generator/util/util.ftl", params)); - //sql generate - result.put("select", freemarkerTool.processString("code-generator/sql/select.ftl", params)); - result.put("insert", freemarkerTool.processString("code-generator/sql/insert.ftl", params)); - result.put("update", freemarkerTool.processString("code-generator/sql/update.ftl", params)); - result.put("delete", freemarkerTool.processString("code-generator/sql/delete.ftl", params)); + // generate the code 需要加新的模板请在里面改 + Map result = generatorService.getResultByParams(params); - // 计算,生成代码行数 - int lineNum = 0; - for (Map.Entry item: result.entrySet()) { - if (item.getValue() != null) { - lineNum += StringUtils.countMatches(item.getValue(), "\n"); - } - } - log.info("生成代码行数:{}", lineNum); - //测试环境可自行开启 - //log.info("生成代码数据:{}", result); return new ReturnT<>(result); } catch (IOException | TemplateException e) { log.error(e.getMessage(), e); - return new ReturnT<>(ReturnT.FAIL_CODE, "表结构解析失败"+e.getMessage()); + return new ReturnT<>(ReturnT.FAIL_CODE, e.getMessage()); + } catch (CodeGenerateException e) { + log.error(e.getMessage(), e); + return new ReturnT<>(ReturnT.FAIL_CODE, e.getMessage()); } } diff --git a/generator-web/src/main/java/com/softdev/system/generator/entity/ParamInfo.java b/generator-web/src/main/java/com/softdev/system/generator/entity/ParamInfo.java new file mode 100644 index 00000000..7ca56fb0 --- /dev/null +++ b/generator-web/src/main/java/com/softdev/system/generator/entity/ParamInfo.java @@ -0,0 +1,25 @@ +package com.softdev.system.generator.entity; + +import lombok.Data; + +/** + * Post data - ParamInfo + * @author zhengkai.blog.csdn.net + */ +@Data +public class ParamInfo { + private String tableSql; + private String authorName; + private String packageName; + private String returnUtil; + private String nameCaseType; + private String tinyintTransType; + private String dataType; + + @Data + public static class NAME_CASE_TYPE{ + public static String CAMEL_CASE="CamelCase"; + public static String UNDER_SCORE_CASE="UnderScoreCase"; + public static String UPPER_UNDER_SCORE_CASE="UpperUnderScoreCase"; + } +} diff --git a/generator-web/src/main/java/com/softdev/system/generator/service/GeneratorService.java b/generator-web/src/main/java/com/softdev/system/generator/service/GeneratorService.java new file mode 100644 index 00000000..85a424bc --- /dev/null +++ b/generator-web/src/main/java/com/softdev/system/generator/service/GeneratorService.java @@ -0,0 +1,17 @@ +package com.softdev.system.generator.service; + +import freemarker.template.TemplateException; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.util.Map; + +/** + * GeneratorService + * @author zhengkai.blog.csdn.net + */ +public interface GeneratorService { + + public Map getResultByParams(Map params) throws IOException, TemplateException; + +} diff --git a/generator-web/src/main/java/com/softdev/system/generator/service/GeneratorServiceImpl.java b/generator-web/src/main/java/com/softdev/system/generator/service/GeneratorServiceImpl.java new file mode 100644 index 00000000..ce857ea2 --- /dev/null +++ b/generator-web/src/main/java/com/softdev/system/generator/service/GeneratorServiceImpl.java @@ -0,0 +1,78 @@ +package com.softdev.system.generator.service; + +import com.softdev.system.generator.util.FreemarkerTool; +import freemarker.template.TemplateException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * GeneratorService + * @author zhengkai.blog.csdn.net + */ +@Slf4j +@Service +public class GeneratorServiceImpl implements GeneratorService { + + @Autowired + private FreemarkerTool freemarkerTool; + + @Override + public Map getResultByParams(Map params) throws IOException, TemplateException { + // result + Map result = new HashMap(32); + + //UI + result.put("swagger-ui", freemarkerTool.processString("code-generator/ui/swagger-ui.ftl", params)); + result.put("element-ui", freemarkerTool.processString("code-generator/ui/element-ui.ftl", params)); + result.put("bootstrap-ui", freemarkerTool.processString("code-generator/ui/bootstrap-ui.ftl", params)); + //mybatis old + result.put("controller", freemarkerTool.processString("code-generator/mybatis/controller.ftl", params)); + result.put("service", freemarkerTool.processString("code-generator/mybatis/service.ftl", params)); + result.put("service_impl", freemarkerTool.processString("code-generator/mybatis/service_impl.ftl", params)); + result.put("mapper", freemarkerTool.processString("code-generator/mybatis/mapper.ftl", params)); + result.put("mybatis", freemarkerTool.processString("code-generator/mybatis/mybatis.ftl", params)); + result.put("model", freemarkerTool.processString("code-generator/mybatis/model.ftl", params)); + //jpa + result.put("entity", freemarkerTool.processString("code-generator/jpa/entity.ftl", params)); + result.put("repository", freemarkerTool.processString("code-generator/jpa/repository.ftl", params)); + result.put("jpacontroller", freemarkerTool.processString("code-generator/jpa/jpacontroller.ftl", params)); + //jdbc template + result.put("jtdao", freemarkerTool.processString("code-generator/jdbc-template/jtdao.ftl", params)); + result.put("jtdaoimpl", freemarkerTool.processString("code-generator/jdbc-template/jtdaoimpl.ftl", params)); + //beetsql + result.put("beetlmd", freemarkerTool.processString("code-generator/beetlsql/beetlmd.ftl", params)); + result.put("beetlentity", freemarkerTool.processString("code-generator/beetlsql/beetlentity.ftl", params)); + result.put("beetlentitydto", freemarkerTool.processString("code-generator/beetlsql/beetlentitydto.ftl", params)); + result.put("beetlcontroller", freemarkerTool.processString("code-generator/beetlsql/beetlcontroller.ftl", params)); + //mybatis plus + result.put("pluscontroller", freemarkerTool.processString("code-generator/mybatis-plus/pluscontroller.ftl", params)); + result.put("plusmapper", freemarkerTool.processString("code-generator/mybatis-plus/plusmapper.ftl", params)); + //util + result.put("util", freemarkerTool.processString("code-generator/util/util.ftl", params)); + result.put("json", freemarkerTool.processString("code-generator/util/json.ftl", params)); + result.put("xml", freemarkerTool.processString("code-generator/util/xml.ftl", params)); + //sql generate + result.put("select", freemarkerTool.processString("code-generator/sql/select.ftl", params)); + result.put("insert", freemarkerTool.processString("code-generator/sql/insert.ftl", params)); + result.put("update", freemarkerTool.processString("code-generator/sql/update.ftl", params)); + result.put("delete", freemarkerTool.processString("code-generator/sql/delete.ftl", params)); + + // 计算,生成代码行数 + /*int lineNum = 0; + for (Map.Entry item: result.entrySet()) { + if (item.getValue() != null) { + lineNum += StringUtils.countMatches(item.getValue(), "\n"); + } + } + log.info("生成代码行数:{}", lineNum);*/ + + //测试环境可自行开启 + //log.info("生成代码数据:{}", result); + return result; + } +} diff --git a/generator-web/src/main/java/com/softdev/system/generator/util/ApiReturnObject.java b/generator-web/src/main/java/com/softdev/system/generator/util/ApiReturnObject.java deleted file mode 100644 index 4b15ae8e..00000000 --- a/generator-web/src/main/java/com/softdev/system/generator/util/ApiReturnObject.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.softdev.system.generator.util; - -import lombok.Data; - -import java.io.Serializable; -@Data -public class ApiReturnObject implements Serializable{ - - private static final long serialVersionUID = 1L; - - public ApiReturnObject(String errorCode, Object errorMessage, Object returnObject) { - super(); - this.errorCode = errorCode; - this.errorMessage = errorMessage; - this.returnObject = returnObject; - } - public ApiReturnObject(Object errorMessage, Object returnObject) { - super(); - this.errorMessage = errorMessage; - this.returnObject = returnObject; - } - - String errorCode="00"; - Object errorMessage; - Object returnObject; - String pageNumber; - String pageSize; - String totalElements; - String totalPages; - - public ApiReturnObject(String pageNumber,String pageSize,String totalElements,String totalPages,String errorCode, Object errorMessage, Object returnObject) { - super(); - this.pageNumber = pageNumber; - this.errorCode = errorCode; - this.errorMessage = errorMessage; - this.returnObject = returnObject; - this.pageSize = pageSize; - this.totalElements = totalElements; - this.totalPages = totalPages; - } - -} diff --git a/generator-web/src/main/java/com/softdev/system/generator/util/ApiReturnUtil.java b/generator-web/src/main/java/com/softdev/system/generator/util/ApiReturnUtil.java deleted file mode 100644 index 8c62aa3f..00000000 --- a/generator-web/src/main/java/com/softdev/system/generator/util/ApiReturnUtil.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.softdev.system.generator.util; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -public class ApiReturnUtil implements Serializable{ - - private static final long serialVersionUID = 1L; - - public static ApiReturnObject error(Object errorMessage) { - System.out.println(errorMessage); - List object=new ArrayList(); - return new ApiReturnObject("01",errorMessage,object); - } - public static ApiReturnObject error(Object errorMessage, Object returnObject) { - List object=new ArrayList(); - object.add(returnObject); - return new ApiReturnObject("01",errorMessage,object); - } - public static ApiReturnObject success(Object returnObject) { - if(returnObject instanceof java.util.List){ - return new ApiReturnObject("00","success",returnObject); - }else { - List object=new ArrayList(); - object.add(returnObject); - return new ApiReturnObject("00","success",object); - } - } - public static ApiReturnObject success(Object errorMessage, Object returnObject) { - if(returnObject instanceof java.util.List){ - return new ApiReturnObject("00",errorMessage,returnObject); - }else { - List object=new ArrayList(); - object.add(returnObject); - return new ApiReturnObject("00",errorMessage,object); - } - } - public static ApiReturnObject pageManual(Integer pageNumber, Integer pageSize,Integer countNum, List returnObject) { - return new ApiReturnObject(pageNumber+"",pageSize+"",countNum+"",getTotalPages(countNum, pageSize),"00","success",returnObject); - } - - public static String getTotalPages(Integer countNum, Integer pageSize) { - if((countNum%pageSize)==0) { - return ((countNum/pageSize))+""; - }else { - return ((countNum/pageSize)+1)+""; - } - } -} diff --git a/generator-web/src/main/java/com/softdev/system/generator/util/BasePath.java b/generator-web/src/main/java/com/softdev/system/generator/util/BasePath.java deleted file mode 100644 index 21dd7897..00000000 --- a/generator-web/src/main/java/com/softdev/system/generator/util/BasePath.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.softdev.system.generator.util; - - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; - -public class BasePath { - protected static String contextPath = null; - protected static String basePath = null; - protected static String realPath = null; - - public static String getBasePath(HttpServletRequest request) { - contextPath = request.getContextPath(); - basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+contextPath+"/"; - return basePath; - } - - public static String getRealPath(HttpServletRequest request, String path) { - ServletContext context = request.getSession().getServletContext(); - realPath = context.getRealPath(path); - realPath = context.getRealPath(path)+"\\"; - return realPath; - } - - public static String getMyRealPath(HttpServletRequest request, String path) { - ServletContext context = request.getSession().getServletContext(); - realPath = context.getRealPath(path); - realPath = context.getRealPath(path); - return realPath; - } -} diff --git a/generator-web/src/main/java/com/softdev/system/generator/util/StringPlusUtils.java b/generator-web/src/main/java/com/softdev/system/generator/util/StringPlusUtils.java deleted file mode 100644 index 4c5d5605..00000000 --- a/generator-web/src/main/java/com/softdev/system/generator/util/StringPlusUtils.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.softdev.system.generator.util; - -/** - * string tool - * - * @author xuxueli 2018-05-02 20:43:25 - */ -public class StringPlusUtils { - - /** - * 首字母大写 - * - * @param str - * @return - */ - public static String upperCaseFirst(String str) { - return str.substring(0, 1).toUpperCase() + str.substring(1); - } - - /** - * 首字母小写 - * - * @param str - * @return - */ - public static String lowerCaseFirst(String str) { - return str.substring(0, 1).toLowerCase() + str.substring(1); - } - - /** - * 下划线,转换为驼峰式 - * - * @param underscoreName - * @return - */ - public static String underlineToCamelCase(String underscoreName) { - StringBuilder result = new StringBuilder(); - if (underscoreName != null && underscoreName.trim().length() > 0) { - boolean flag = false; - for (int i = 0; i < underscoreName.length(); i++) { - char ch = underscoreName.charAt(i); - if ("_".charAt(0) == ch) { - flag = true; - } else { - if (flag) { - result.append(Character.toUpperCase(ch)); - flag = false; - } else { - result.append(ch); - } - } - } - } - return result.toString(); - } - -} diff --git a/generator-web/src/main/java/com/softdev/system/generator/util/TableParseUtil.java b/generator-web/src/main/java/com/softdev/system/generator/util/TableParseUtil.java index cd1fb159..843bf3eb 100644 --- a/generator-web/src/main/java/com/softdev/system/generator/util/TableParseUtil.java +++ b/generator-web/src/main/java/com/softdev/system/generator/util/TableParseUtil.java @@ -1,8 +1,14 @@ package com.softdev.system.generator.util; +import cn.hutool.core.util.XmlUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; import com.softdev.system.generator.entity.ClassInfo; import com.softdev.system.generator.entity.FieldInfo; +import com.softdev.system.generator.entity.ParamInfo; +import org.w3c.dom.Document; import java.io.IOException; import java.math.BigDecimal; @@ -13,24 +19,32 @@ import java.util.regex.Pattern; /** - * @author xuxueli 2018-05-02 21:10:45 - * @modify zhengk/moshow 20180913 + * @author zhengkai.blog.csdn.net */ public class TableParseUtil { /** * 解析建表SQL生成代码(model-dao-xml) * - * @param tableSql + * @param paramInfo * @return */ - public static ClassInfo processTableIntoClassInfo(String tableSql, boolean isUnderLineToCamelCase,String tinyintTransType) + public static ClassInfo processTableIntoClassInfo(ParamInfo paramInfo) throws IOException { + //process the param + String tableSql=paramInfo.getTableSql(); + String nameCaseType=paramInfo.getNameCaseType(); + String tinyintTransType=paramInfo.getTinyintTransType(); + if (tableSql==null || tableSql.trim().length()==0) { throw new CodeGenerateException("Table structure can not be empty."); } + //deal with special character tableSql = tableSql.trim().replaceAll("'","`").replaceAll("\"","`").replaceAll(",",",").toLowerCase(); - + //deal with java string copy \n" + System.out.println(tableSql); + tableSql = tableSql.trim().replaceAll("n`","").replaceAll("\\+","").replaceAll("``","`").replaceAll("\\\\",""); + System.out.println(tableSql); // table Name String tableName = null; if (tableSql.contains("TABLE") && tableSql.contains("(")) { @@ -150,10 +164,10 @@ public static ClassInfo processTableIntoClassInfo(String tableSql, boolean isUnd // 2019-2-22 zhengkai 要在条件中使用复杂的表达式 // 2019-4-29 zhengkai 优化对普通和特殊storage关键字的判断(感谢@AhHeadFloating的反馈 ) boolean specialFlag=(!columnLine.contains("key ")&&!columnLine.contains("constraint")&&!columnLine.contains("using")&&!columnLine.contains("unique") - &&!(columnLine.contains("primary")&&columnLine.indexOf("storage")+3>columnLine.indexOf("(")) + &&!(columnLine.contains("primary ")&&columnLine.indexOf("storage")+3>columnLine.indexOf("(")) &&!columnLine.contains("pctincrease") &&!columnLine.contains("buffer_pool")&&!columnLine.contains("tablespace") - &&!(columnLine.contains("primary")&&i>3)); + &&!(columnLine.contains("primary ")&&i>3)); if (specialFlag){ //如果是oracle的number(x,x),可能出现最后分割残留的,x),这里做排除处理 if(columnLine.length()<5) {continue;} @@ -164,14 +178,18 @@ public static ClassInfo processTableIntoClassInfo(String tableSql, boolean isUnd columnName = columnLine.substring(0, columnLine.indexOf(" ")); // field Name // 2019-09-08 yj 添加是否下划线转换为驼峰的判断 - String fieldName; - if(isUnderLineToCamelCase){ + String fieldName=null; + if(ParamInfo.NAME_CASE_TYPE.CAMEL_CASE.equals(nameCaseType)){ fieldName = StringUtils.lowerCaseFirst(StringUtils.underlineToCamelCase(columnName)); if (fieldName.contains("_")) { fieldName = fieldName.replaceAll("_", ""); } - }else { + }else if(ParamInfo.NAME_CASE_TYPE.UNDER_SCORE_CASE.equals(nameCaseType)){ fieldName = StringUtils.lowerCaseFirst(columnName); + }else if(ParamInfo.NAME_CASE_TYPE.UPPER_UNDER_SCORE_CASE.equals(nameCaseType)){ + fieldName = StringUtils.lowerCaseFirst(columnName.toUpperCase()); + }else{ + fieldName=columnName; } // field class @@ -290,5 +308,118 @@ public static ClassInfo processTableIntoClassInfo(String tableSql, boolean isUnd return codeJavaInfo; } + /** + * parse JSON + * @param paramInfo + * @return + */ + public static ClassInfo processJsonToClassInfo(ParamInfo paramInfo){ + ClassInfo codeJavaInfo = new ClassInfo(); + codeJavaInfo.setTableName("JsonDto"); + codeJavaInfo.setClassName("JsonDto"); + codeJavaInfo.setClassComment("JsonDto"); + + //support children json if forget to add '{' in front of json + if(paramInfo.getTableSql().trim().startsWith("\"")){ + paramInfo.setTableSql("{"+paramInfo.getTableSql()); + } + if(JSON.isValid(paramInfo.getTableSql())){ + if(paramInfo.getTableSql().trim().startsWith("{")){ + JSONObject jsonObject = JSONObject.parseObject(paramInfo.getTableSql().trim()); + //parse FieldList by JSONObject + codeJavaInfo.setFieldList(processJsonObjectToFieldList(jsonObject)); + }else if(paramInfo.getTableSql().trim().startsWith("[")){ + JSONArray jsonArray=JSONArray.parseArray(paramInfo.getTableSql().trim()); + //parse FieldList by JSONObject + codeJavaInfo.setFieldList(processJsonObjectToFieldList(jsonArray.getJSONObject(0))); + } + } + return codeJavaInfo; + } + /** + * parse SQL by regex + * @author https://github.com/ydq + * @param paramInfo + * @return + */ + public static ClassInfo processTableToClassInfoByRegex(ParamInfo paramInfo){ + // field List + List fieldList = new ArrayList(); + //return classInfo + ClassInfo codeJavaInfo = new ClassInfo(); + + //匹配整个ddl,将ddl分为表名,列sql部分,表注释 + String DDL_PATTEN_STR="\\s*create\\s+table\\s+(?\\S+)[^\\(]*\\((?[\\s\\S]+)\\)[^\\)]+?(comment\\s*(=|on\\s+table)\\s*'(?.*?)'\\s*;?)?$"; + + Pattern DDL_PATTERN = Pattern.compile(DDL_PATTEN_STR, Pattern.CASE_INSENSITIVE); + + //匹配列sql部分,分别解析每一列的列名 类型 和列注释 + String COL_PATTERN_STR="\\s*(?\\S+)\\s+(?\\w+)\\s*(?:\\([\\s\\d,]+\\))?((?!comment).)*(comment\\s*'(?.*?)')?\\s*(,|$)"; + + Pattern COL_PATTERN = Pattern.compile(COL_PATTERN_STR, Pattern.CASE_INSENSITIVE); + + Matcher matcher = DDL_PATTERN.matcher(paramInfo.getTableSql().trim()); + if (matcher.find()){ + String tableName = matcher.group("tableName"); + String tableComment = matcher.group("tableComment"); + codeJavaInfo.setTableName(tableName.replaceAll("'","")); + codeJavaInfo.setClassName(tableName.replaceAll("'","")); + codeJavaInfo.setClassComment(tableComment.replaceAll("'","")); + String columnsSQL = matcher.group("columnsSQL"); + if (columnsSQL != null && columnsSQL.length() > 0){ + Matcher colMatcher = COL_PATTERN.matcher(columnsSQL); + while (colMatcher.find()){ + String fieldName = colMatcher.group("fieldName"); + String fieldType = colMatcher.group("fieldType"); + String fieldComment = colMatcher.group("fieldComment"); + if (!"key".equalsIgnoreCase(fieldType)){ + FieldInfo fieldInfo = new FieldInfo(); + fieldInfo.setFieldName(fieldName.replaceAll("'","")); + fieldInfo.setColumnName(fieldName.replaceAll("'","")); + fieldInfo.setFieldClass(fieldType.replaceAll("'","")); + fieldInfo.setFieldComment(fieldComment.replaceAll("'","")); + fieldList.add(fieldInfo); + } + } + } + codeJavaInfo.setFieldList(fieldList); + } + return codeJavaInfo; + } + public static List processJsonObjectToFieldList(JSONObject jsonObject){ + // field List + List fieldList = new ArrayList(); + jsonObject.keySet().stream().forEach(jsonField->{ + FieldInfo fieldInfo = new FieldInfo(); + fieldInfo.setFieldName(jsonField); + fieldInfo.setColumnName(jsonField); + fieldInfo.setFieldClass(String.class.getSimpleName()); + fieldInfo.setFieldComment("father:"+jsonField); + fieldList.add(fieldInfo); + if(jsonObject.get(jsonField) instanceof JSONArray){ + jsonObject.getJSONArray(jsonField).stream().forEach(arrayObject->{ + FieldInfo fieldInfo2 = new FieldInfo(); + fieldInfo2.setFieldName(arrayObject.toString()); + fieldInfo2.setColumnName(arrayObject.toString()); + fieldInfo2.setFieldClass(String.class.getSimpleName()); + fieldInfo2.setFieldComment("children:"+arrayObject.toString()); + fieldList.add(fieldInfo2); + }); + }else if(jsonObject.get(jsonField) instanceof JSONObject){ + jsonObject.getJSONObject(jsonField).keySet().stream().forEach(arrayObject->{ + FieldInfo fieldInfo2 = new FieldInfo(); + fieldInfo2.setFieldName(arrayObject.toString()); + fieldInfo2.setColumnName(arrayObject.toString()); + fieldInfo2.setFieldClass(String.class.getSimpleName()); + fieldInfo2.setFieldComment("children:"+arrayObject.toString()); + fieldList.add(fieldInfo2); + }); + } + }); + if(fieldList.size()<1){ + throw new CodeGenerateException("JSON解析失败"); + } + return fieldList; + } } diff --git a/generator-web/src/main/resources/templates/code-generator/util/json.ftl b/generator-web/src/main/resources/templates/code-generator/util/json.ftl new file mode 100644 index 00000000..a0be13a6 --- /dev/null +++ b/generator-web/src/main/resources/templates/code-generator/util/json.ftl @@ -0,0 +1,7 @@ +<#if classInfo.fieldList?exists && classInfo.fieldList?size gt 0> +{ +<#list classInfo.fieldList as fieldItem> + "${fieldItem.fieldName}":""<#if fieldItem_has_next>, + +} + diff --git a/generator-web/src/main/resources/templates/code-generator/util/util.ftl b/generator-web/src/main/resources/templates/code-generator/util/util.ftl index 71767456..13da0abc 100644 --- a/generator-web/src/main/resources/templates/code-generator/util/util.ftl +++ b/generator-web/src/main/resources/templates/code-generator/util/util.ftl @@ -13,4 +13,9 @@ ${fieldItem.fieldClass} ${fieldItem.fieldName} = ${classInfo.className?uncap_fir // ${fieldItem.fieldComment} ${classInfo.className?uncap_first}.set${fieldItem.fieldName?cap_first}(); + +<#list classInfo.fieldList as fieldItem> +// ${fieldItem.fieldComment} +${classInfo.className?uncap_first}.set${fieldItem.fieldName?cap_first}(${classInfo.className?uncap_first}2.get${fieldItem.fieldName?cap_first}();); + diff --git a/generator-web/src/main/resources/templates/code-generator/util/xml.ftl b/generator-web/src/main/resources/templates/code-generator/util/xml.ftl new file mode 100644 index 00000000..d8156578 --- /dev/null +++ b/generator-web/src/main/resources/templates/code-generator/util/xml.ftl @@ -0,0 +1,11 @@ + +<#if classInfo.fieldList?exists && classInfo.fieldList?size gt 0> +<${classInfo.className}> +<#list classInfo.fieldList as fieldItem> + <${fieldItem.fieldName}> + + + diff --git a/generator-web/src/main/resources/templates/common/common-import.ftl b/generator-web/src/main/resources/templates/common/common-import.ftl index c307aaea..3e6c4241 100644 --- a/generator-web/src/main/resources/templates/common/common-import.ftl +++ b/generator-web/src/main/resources/templates/common/common-import.ftl @@ -16,6 +16,8 @@ + + + - diff --git a/generator-web/src/main/resources/templates/index.ftl b/generator-web/src/main/resources/templates/index.ftl index 4195e2e3..3433d28f 100644 --- a/generator-web/src/main/resources/templates/index.ftl +++ b/generator-web/src/main/resources/templates/index.ftl @@ -9,7 +9,6 @@ <@netCommon.commonStyle /> <@netCommon.commonScript /> - <#---->