6 Commits

27 changed files with 335 additions and 167 deletions

View File

@@ -1,7 +1,7 @@
# 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)
![image](https://img.shields.io/badge/SpringBoot2-%E2%98%85%E2%98%85%E2%98%85%E2%98%85%E2%98%85-blue.svg)
![image](https://img.shields.io/badge/Freemarker-%E2%98%85%E2%98%85%E2%98%85%E2%98%85%E2%98%85-blue.svg)
![image](https://img.shields.io/badge/CodeGenerator-%E2%98%85%E2%98%85%E2%98%85%E2%98%85%E2%98%85-blue.svg)
[![Build Status](https://travis-ci.org/moshowgame/SpringBootCodeGenerator.svg?branch=master)](https://travis-ci.org/moshowgame/SpringBootCodeGenerator)
@@ -12,16 +12,16 @@
- √ 用DDL-SQL语句生成JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL相关代码.
# Advantage
- 支持DDL SQL/INSERT SQL/SIMPLE JSON生成模式
- 自动记忆最近生成的内容最多保留9个
- 支持特殊字符模板(`#`请用`井`代替;`$`请用`¥`代替)
- 提供众多通用模板易于使用复制粘贴加简单修改即可完成CRUD操作
- 支持JSON逆向生成(只支持简单的一级树)
- 支持特殊字符模板(`#`请用`井`代替;`$`请用`¥`代替)
- 根据comment=(mysql)或者comment on table(pgsql/oracle)生成类名注释
# Url
|访问路径|http://localhost:1234/generator|
|-|-|
|----|----|
|在线地址|http://java.bejson.com/generator|
|CSDN博客|http://zhengkai.blog.csdn.net|
|最新Jar包|https://github.com/moshowgame/SpringBootCodeGenerator/releases|
@@ -32,42 +32,45 @@
# Update
|更新日期|更新内容|
|-|-|
|20200517|1.代码重构异常处理优化Freemarker相关工具类优化简化模板生成部分通过template.json来配置需要生成的模板不需要配置java文件。 2.修复包含comment关键字时注释无法识别的问题。(感谢@1nchaos的反馈) 3.赞赏优化,感谢大家的赞赏 4.新增mapper2(Mybatis-Annotation模板)(感谢@baisi525和@CHKEGit的建议)。|
|20200503|1.优化对特殊字符的处理,对于包含#和$等特殊字符的在模板使用井和¥代替便可escapeString方法会自动处理<br> 2.优化mybatisplus实体类相关(感谢@chunchengmeigui的反馈) 3.修优化对所有类型的判断(感谢@cnlw的反馈) 4.移除swagger-entity该功能已经包含在swagger-ui的下拉选项中 5.升级hutool和lombok版本|
|20200306|1.提交一套layuimini+mybatisplus的模板. 2.修复mybatisplus一些相关问题. |
|20200206|1.新增历史记录功能,自动保存最近生成的对象 2.新增swagger开关选项和修复@Column带name参数(感谢@liuyu-struggle的建议) 3.去除mybatis模板中的方括号[]和修改模板里的类注释样式(感谢@gaohanghang的PR)|
|20191229|1.修复bejson安全防护策略拦截问题(感谢@liangbintao和@1808083642的反馈) 2.优化字段名含date字符串的处理(感谢@smilexzh的反馈) 3.控制台动态输出项目访问地址(感谢@gaohanghang的提交)|
|20191128|1.修复支持string-copy导致的以n结尾的字母不显示问题 2.jpa-entity新增swagger@ApiModel@ApiModelProperty注解和SQL字段@Column注解(感谢@yjq907的建议) |
|20191126|1.springboot2内置tomcat更换为性能更强大的undertow 2.修复tinyintTransType参数丢失问题 |
|20191124|1.java代码结构优化. 2.新增简单的json生成模式 3.新增简单的正则表达式匹配模式(感谢@ydq的贡献) 4.新增对复制String代码中的乱SQL代码的支持 5.优化对JSON的父子节点/处理JSONObject和JSONArray节点处理子节点缺失'{'头处理|
|20191123|1.移除频繁出错和被过滤的layer,改为jquery-toast. 2.Util功能优化,新增json和xml.|
|----|----|
|20200621|修复FreemarkerUtil的Path问题导致JAR包运行时无法获取template的问题。|
|20200525|1.一些fix,关于封装工具类以及layui模板优化等.<br> 2.优化表备注的获取逻辑.<br> 3.生成时间格式改为yyyy-MM-dd,移除具体的时间,只保留日期|
|20200522|1.新增insert-sql模式,支持对"insert into table (xxx) values (xxx)"语句进行处理,生成java代码(感谢三叔的建议).|
|20200517|1.代码重构!异常处理优化,Freemarker相关工具类优化,简化模板生成部分,通过template.json来配置需要生成的模板,不需要配置java文件.<br> 2.修复包含comment关键字时注释无法识别的问题.(感谢@1nchaos的反馈).<br> 3.赞赏优化,感谢大家的赞赏.<br> 4.新增mapper2(Mybatis-Annotation模板)(感谢@baisi525和@CHKEGit的建议).|
|20200503|1.优化对特殊字符的处理,对于包含#和$等特殊字符的,在模板使用井和¥代替便可,escapeString方法会自动处理.<br> 2.优化mybatisplus实体类相关(感谢@chunchengmeigui的反馈).<br> 3.修优化对所有类型的判断(感谢@cnlw的反馈).<br> 4.移除swagger-entity,该功能已经包含在swagger-ui的下拉选项中 <br> 5.升级hutool和lombok版本|
|20200306|1.提交一套layuimini+mybatisplus的模板.<br> 2.修复mybatisplus一些相关问题. |
|20200206|1.新增历史记录功能,自动保存最近生成的对象.<br> 2.新增swagger开关选项和修复@Column带name参数(感谢@liuyu-struggle的建议).<br> 3.去除mybatis模板中的方括号[]和修改模板里的类注释样式(感谢@gaohanghang的PR)|
|20191229|1.修复bejson安全防护策略拦截问题(感谢@liangbintao和@1808083642的反馈).<br> 2.优化字段名含date字符串的处理(感谢@smilexzh的反馈).<br> 3.控制台动态输出项目访问地址(感谢@gaohanghang的提交)|
|20191128|1.修复支持string-copy导致的以n结尾的字母不显示问题.<br> 2.jpa-entity新增swagger@ApiModel@ApiModelProperty注解和SQL字段@Column注解(感谢@yjq907的建议) |
|20191126|1.springboot2内置tomcat更换为性能更强大的undertow.<br> 2.修复tinyintTransType参数丢失问题 |
|20191124|1.java代码结构优化.<br> 2.新增简单的json生成模式.<br> 3.新增简单的正则表达式匹配模式(感谢@ydq的贡献).<br> 4.新增对复制String代码中的乱SQL代码的支持 5.优化对JSON的父子节点/处理,JSONObject和JSONArray节点处理,子节点缺失'{'头处理|
|20191123|1.移除频繁出错和被过滤的layer,改为jquery-toast.<br> 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.其他一些优化. |
|20191115|1.添加tinyint类型转换(感谢@lixiliang&@liujiansgit的Suggestion).<br> 2.添加一键复制功能(感谢@gaohanghang的Suggestion).<br> 3.Mybatis的insert增加keyProperty="id"用于返回自增id(感谢@88888888888888888888的Suggestion).<br> 4.优化date类型的支持(感谢@SteveLsf的反馈).<br> 5.其他一些优化. |
|20191015|修复jdbcTemplates中insert语句第一个字段丢失的问题. |
|20190915|1.添加对象getset模板 2.添加sql模板 3.启动类添加日志输出方便项目使用(感谢@gaohanghang 的pull request) |
|20190910|优化以及更新Maven依赖减少打包体积. 1.修复mapper接口load方法但是xml中方法不匹配问题 2.移除mapper中CRUD时的@param 注解会影响xml的解析(感谢@caojiantao的反馈).3.优化MyBatis的xml文件对Oracle的支持.(感谢@wylove1992的反馈) 4.新增对boolean的处理(感谢@violinxsc的反馈)以及优化tinyint类型生成boolean类型问题(感谢@hahaYhui的反馈) |
|20190915|1.添加对象getset模板.<br> 2.添加sql模板.<br> 3.启动类添加日志输出,方便项目使用(感谢@gaohanghang 的pull request) |
|20190910|优化以及更新Maven依赖,减少打包体积.<br> 1.修复mapper接口load方法,但是xml中方法不匹配问题.<br> 2.移除mapper中CRUD时的@param 注解,会影响xml的解析(感谢@caojiantao的反馈).<br> 3.优化MyBatis的xml文件对Oracle的支持.(感谢@wylove1992的反馈).<br> 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类型增加intlongBigDecimal的区分判断(感谢@lshz0088的指导).|
|20190518|1.优化注释.<br> 2.修改 mybatis模板中 controller注解.<br> 3.修改 mybatis模板中 dao文件使用为 mapper文件.<br> 4.修改 mybatis模板中 service实现类中的一个 bug.<br> 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|新增返回封装工具类设置.<br> 优化对oracle注释comment on column的支持(感谢@liukex反馈).<br> 优化对普通和特殊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的反馈).<br> 修复JdbcTemplates模板两处错误(感谢@everflourish的反馈).|
|20181212|首页UI优化.<br> 新增MybatisPlus模块(感谢@三叔同事的建议).<br> 修复作者名和包名获取失败问题(感谢@Yanch1994的反馈).|
|20181122|优化正则表达式点号的处理,优化处理字段类型,对number类型增加int,long,BigDecimal的区分判断(感谢@lshz0088的指导).|
|20181108|修复非字段描述"KEY FK_xxxx (xxxx)"导致生成KEY字段情况(感谢@tornadoorz反馈).|
|20181018|支持double(x,x)的类型以及comment里面包含一些特殊字符的处理(感谢@tanwubo的反馈).|
|20181010|CDN变更修复CDN不稳定导致网页js报错问题.|
|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如果不是请手工修改.|
|20181002|修复公共CDN之Layer.js404问题,导致项目无法生成.|
|20180927|优化COMMENT提取逻辑,支持多种复杂情况的注释(感谢@raodeming的反馈).|
|20180926|全新BeetlSQL模块,以及一些小细节优化(感谢@三叔同事的建议).|
|20180925|优化SQL表和字段备注的推断,包括pgsql/oralce的comment on column/table情况处理等.|
|20180918|优化SQL类型推断.<br> 优化PrimaryKey判断.<br> 修复jpacontroller中Repository拼写错误问题.|
|20180917|全新首页,静态文件全部采用CDN.新增jdbcTemplate模块.|
|20180916|1.优化oracle支持,优化DDL语句中"或者'或者空格的支持.<br> 2.补充char/clob/blob/json等类型,如果类型未知,默认为String.|
|20180915|新增Swagger-UI模板.修复一些命名和导入问题.JPA的Entity默认第一个字段为Id,如果不是请手工修改.|
|20180913|修复字段没有描述以及类型为DATE型导致的问题.新增JPA的Controller模板.|
|20180831|初始化项目.新增JPA系列Entity+Repository模板.|

View File

@@ -14,7 +14,7 @@ public class GlobalDefaultExceptionHandler {
@ResponseBody
public ReturnT defaultExceptionHandler(HttpServletRequest req,Exception e) {
e.printStackTrace();
return new ReturnT<>(ReturnT.FAIL_CODE, e.getMessage());
return ReturnT.ERROR(e.getMessage());
}
}

View File

@@ -34,10 +34,10 @@ public class IndexController {
@PostMapping("/genCode")
@ResponseBody
public ReturnT<Map<String, String>> codeGenerate(@RequestBody ParamInfo paramInfo ) throws Exception {
public ReturnT codeGenerate(@RequestBody ParamInfo paramInfo ) throws Exception {
if (paramInfo.getTableSql().trim().length()<1) {
return new ReturnT<>(ReturnT.FAIL_CODE, "表结构信息不可为空");
return ReturnT.ERROR("表结构信息不可为空");
}
//1.Parse Table Structure 表结构解析
@@ -45,6 +45,8 @@ public class IndexController {
switch (paramInfo.getDataType()){
//JSON模式parse field from json string
case "json":classInfo = TableParseUtil.processJsonToClassInfo(paramInfo);break;
//INSERT SQL模式parse field from insert sql
case "insert-sql":classInfo = TableParseUtil.processInsertSqlToClassInfo(paramInfo);break;
//正则表达式模式非完善版本parse sql by regex
case "sql-regex":classInfo = TableParseUtil.processTableToClassInfoByRegex(paramInfo);break;
//默认模式default parse sql by java
@@ -66,7 +68,7 @@ public class IndexController {
//3.generate the code by freemarker template and param . Freemarker根据参数和模板生成代码
Map<String, String> result = generatorService.getResultByParams(params);
return new ReturnT<>(result);
return ReturnT.SUCCESS(result);
}
}

View File

@@ -5,29 +5,61 @@ import lombok.Data;
import java.io.Serializable;
/**
* common return
* @author xuxueli 2015-12-4 16:32:31
* common returnT:公共返回封装类
* @author zhengkai.blog.csdn.net
*/
@Data
public class ReturnT<T> implements Serializable {
public class ReturnT implements Serializable {
public static final long serialVersionUID = 42L;
public static final int SUCCESS_CODE = 200;
public static final int FAIL_CODE = 500;
public static final ReturnT<String> SUCCESS = new ReturnT<>(null);
public static final ReturnT<String> FAIL = new ReturnT<>(FAIL_CODE, null);
public static final int PAGE_CODE = 0;
public static final String OBJECT_NOT_FOUND = "找不到该对象";
public static final String OPERATION_SUCCESS = "操作成功";
private int code;
private String msg;
private T data;
private Object data;
private int count;
public ReturnT(int code, String msg) {
this.code = code;
this.msg = msg;
}
public ReturnT(T data) {
public ReturnT(int code, String msg,Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public ReturnT(Object data) {
this.code = SUCCESS_CODE;
this.data = data;
}
public ReturnT( Object data , int count ) {
this.code = PAGE_CODE;
this.data = data;
this.count = count;
}
public static ReturnT PAGE( Object data , int count){
return new ReturnT(data,count);
}
public static ReturnT PAGE( Object data , long count){
return new ReturnT(data,Integer.parseInt(count+""));
}
public static ReturnT SUCCESS(){
return new ReturnT(SUCCESS_CODE,OPERATION_SUCCESS);
}
public static ReturnT SUCCESS(String msg){
return new ReturnT(SUCCESS_CODE,msg);
}
public static ReturnT SUCCESS(Object data){
return new ReturnT(data);
}
public static ReturnT ERROR(String msg){
return new ReturnT(FAIL_CODE,msg);
}
public static ReturnT ERROR(){
return new ReturnT(FAIL_CODE,OBJECT_NOT_FOUND);
}
}

View File

@@ -1,5 +1,6 @@
package com.softdev.system.generator.util;
import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
@@ -8,7 +9,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Locale;
@@ -40,20 +40,17 @@ public class FreemarkerUtil {
*/
private static Configuration freemarkerConfig = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
static{
String templatePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
int wei = templatePath.lastIndexOf("WEB-INF/classes/");
if (wei > -1) {
templatePath = templatePath.substring(0, wei);
}
try {
freemarkerConfig.setDirectoryForTemplateLoading(new File(templatePath, "templates/code-generator"));
//2020-06-21 zhengkai 修复path问题导致jar无法运行而本地项目可以运行的bug
freemarkerConfig.setClassForTemplateLoading(FreemarkerUtil.class, "/templates/code-generator");
freemarkerConfig.setTemplateLoader(new ClassTemplateLoader(FreemarkerUtil.class, "/templates/code-generator"));
//freemarkerConfig.setDirectoryForTemplateLoading(new File(templatePath, "templates/code-generator"));
freemarkerConfig.setNumberFormat("#");
freemarkerConfig.setClassicCompatible(true);
freemarkerConfig.setDefaultEncoding("UTF-8");
freemarkerConfig.setLocale(Locale.CHINA);
freemarkerConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
} catch (IOException e) {
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}

View File

@@ -11,8 +11,10 @@ import com.softdev.system.generator.entity.ParamInfo;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -78,28 +80,17 @@ public class TableParseUtil {
// class Comment
String classComment = null;
//mysql是comment=,pgsql/oracle是comment on table,
if (tableSql.contains("comment=")) {
String classCommentTmp = tableSql.substring(tableSql.lastIndexOf("comment=")+8).replaceAll("`","").trim();
if (classCommentTmp.indexOf(" ")!=classCommentTmp.lastIndexOf(" ")) {
classCommentTmp = classCommentTmp.substring(classCommentTmp.indexOf(" ")+1, classCommentTmp.lastIndexOf(" "));
}
if (classCommentTmp!=null && classCommentTmp.trim().length()>0) {
classComment = classCommentTmp;
}else{
//修复表备注为空问题
classComment = className;
}
}else if(tableSql.contains("comment on table")) {
//COMMENT ON TABLE CT_BAS_FEETYPE IS 'CT_BAS_FEETYPE';
String classCommentTmp = tableSql.substring(tableSql.lastIndexOf("comment on table")+17).trim();
//证明这是一个常规的COMMENT ON TABLE xxx IS 'xxxx'
//2020-05-25 优化表备注的获取逻辑
if (tableSql.contains("comment=")||tableSql.contains("comment on table")) {
String classCommentTmp = (tableSql.contains("comment="))?
tableSql.substring(tableSql.lastIndexOf("comment=")+8).trim():tableSql.substring(tableSql.lastIndexOf("comment on table")+17).trim();
if (classCommentTmp.contains("`")) {
classCommentTmp = classCommentTmp.substring(classCommentTmp.indexOf("`")+1);
classCommentTmp = classCommentTmp.substring(0,classCommentTmp.indexOf("`"));
classComment = classCommentTmp;
}else{
//非常规的没法分析
classComment = tableName;
classComment = className;
}
}else{
//修复表备注为空问题
@@ -421,4 +412,61 @@ public class TableParseUtil {
}
return fieldList;
}
public static ClassInfo processInsertSqlToClassInfo(ParamInfo paramInfo) {
// field List
List<FieldInfo> fieldList = new ArrayList<FieldInfo>();
//return classInfo
ClassInfo codeJavaInfo = new ClassInfo();
//get origin sql
String fieldSqlStr = paramInfo.getTableSql().toLowerCase().trim();
fieldSqlStr=fieldSqlStr.replaceAll(" "," ").replaceAll("\\\\n`","")
.replaceAll("\\+","").replaceAll("``","`").replaceAll("\\\\","");
String valueStr = fieldSqlStr.substring(fieldSqlStr.lastIndexOf("values")+6).replaceAll(" ","").replaceAll("\\(","").replaceAll("\\)","");
//get the string between insert into and values
fieldSqlStr=fieldSqlStr.substring(0,fieldSqlStr.lastIndexOf("values"));
System.out.println(fieldSqlStr);
String insertSqlPattenStr = "insert into (?<tableName>.*) \\((?<columnsSQL>.*)\\)";
//String DDL_PATTEN_STR="\\s*create\\s+table\\s+(?<tableName>\\S+)[^\\(]*\\((?<columnsSQL>[\\s\\S]+)\\)[^\\)]+?(comment\\s*(=|on\\s+table)\\s*'(?<tableComment>.*?)'\\s*;?)?$";
Matcher matcher1 = Pattern.compile(insertSqlPattenStr).matcher(fieldSqlStr);
while(matcher1.find()){
String tableName = matcher1.group("tableName");
//System.out.println("tableName:"+tableName);
codeJavaInfo.setClassName(tableName);
codeJavaInfo.setTableName(tableName);
String columnsSQL = matcher1.group("columnsSQL");
//System.out.println("columnsSQL:"+columnsSQL);
List<String> valueList = new ArrayList<>();
//add values as comment
Arrays.stream(valueStr.split(",")).forEach(column->{
valueList.add(column);
});
AtomicInteger n= new AtomicInteger(0);
//add column to fleldList
Arrays.stream(columnsSQL.replaceAll(" ", "").split(",")).forEach(column->{
FieldInfo fieldInfo2 = new FieldInfo();
fieldInfo2.setFieldName(column);
fieldInfo2.setColumnName(column);
fieldInfo2.setFieldClass(String.class.getSimpleName());
if(n.get()<valueList.size()){
fieldInfo2.setFieldComment(column+" , eg."+valueList.get(n.get()));
}
fieldList.add(fieldInfo2);
n.getAndIncrement();
});
}
if(fieldList.size()<1){
throw new CodeGenerateException("INSERT SQL解析失败");
}
codeJavaInfo.setFieldList(fieldList);
return codeJavaInfo;
}
}

View File

@@ -40,6 +40,9 @@ spring:
expose-request-attributes: true
expose-session-attributes: true
expose-spring-macro-helpers: true
#template-loader-path: classpath:/templates/
settings:
number_format: 0.##
default_encoding: UTF-8
#template_loader: /templates/
mvc:
static-path-pattern: /static/**

View File

@@ -1 +1 @@
{"version": "20200517"}
{"version": "20200522"}

View File

@@ -9,7 +9,7 @@ import java.util.Map;
/**
* @description ${classInfo.classComment}
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd HH:mm:ss')}
* @date ${.now?string('yyyy-MM-dd')}
*/
@RestController
@RequestMapping("/${classInfo.className?uncap_first}")

View File

@@ -6,7 +6,7 @@ import java.util.List;
/**
* @description ${classInfo.classComment}
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd HH:mm:ss')}
* @date ${.now?string('yyyy-MM-dd')}
*/
@Data<#if swagger?exists && swagger==true>
@ApiModel("${classInfo.classComment}")</#if>

View File

@@ -4,7 +4,7 @@ import java.util.List;
/**
* @description ${classInfo.classComment}
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd HH:mm:ss')}
* @date ${.now?string('yyyy-MM-dd')}
*/
public interface I${classInfo.className}DAO {

View File

@@ -8,7 +8,7 @@ import java.util.List;
/**
* @description ${classInfo.classComment}
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd HH:mm:ss')}
* @date ${.now?string('yyyy-MM-dd')}
*/
@Repository
public class ${classInfo.className}DaoImpl implements I${classInfo.className}Dao{

View File

@@ -15,7 +15,7 @@ import io.swagger.annotations.ApiModelProperty;
/**
* @description ${classInfo.classComment}
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd HH:mm:ss')}
* @date ${.now?string('yyyy-MM-dd')}
*/
@Entity
@Data

View File

@@ -17,7 +17,7 @@ import java.util.Map;
/**
* @description ${classInfo.classComment}
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd HH:mm:ss')}
* @date ${.now?string('yyyy-MM-dd')}
*/
@RestController
@RequestMapping("/${classInfo.className?uncap_first}")

View File

@@ -16,7 +16,7 @@ import org.springframework.stereotype.Repository;
/**
* @description ${classInfo.classComment}
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd HH:mm:ss')}
* @date ${.now?string('yyyy-MM-dd')}
*/
@Repository
public interface ${classInfo.className}Repository extends JpaRepository<${classInfo.className},Integer> {

View File

@@ -20,7 +20,7 @@ import java.util.Map;
/**
* @description ${classInfo.classComment}
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd HH:mm:ss')}
* @date ${.now?string('yyyy-MM-dd')}
*/
@Slf4j
@RestController
@@ -37,17 +37,17 @@ public class ${classInfo.className}Controller {
public Object save(@RequestBody ${classInfo.className} ${classInfo.className?uncap_first}){
log.info("${classInfo.className?uncap_first}:"+JSON.toJSONString(${classInfo.className?uncap_first}));
${classInfo.className} old${classInfo.className} = ${classInfo.className?uncap_first}Mapper.selectOne(new QueryWrapper<${classInfo.className}>().eq("${classInfo.className?uncap_first}_id",${classInfo.className?uncap_first}.get${classInfo.className}Id()));
${classInfo.className?uncap_first}.setModifyDate(new Date());
${classInfo.className?uncap_first}.setUpdateTime(new Date());
if(old${classInfo.className}!=null){
${classInfo.className?uncap_first}Mapper.updateById(${classInfo.className?uncap_first});
}else{
if(${classInfo.className?uncap_first}Mapper.selectOne(new QueryWrapper<${classInfo.className}>().eq("${classInfo.className?uncap_first}_name",${classInfo.className?uncap_first}.get${classInfo.className}Name()))!=null){
return new ReturnT<>(ReturnT.FAIL_CODE,"保存失败,名字重复");
return ${returnUtil}.ERROR("保存失败,名字重复");
}
${classInfo.className?uncap_first}.setCreateDate(new Date());
${classInfo.className?uncap_first}.setCreateTime(new Date());
${classInfo.className?uncap_first}Mapper.insert(${classInfo.className?uncap_first});
}
return new ReturnT<>(ReturnT.SUCCESS_CODE,"保存成功");
return ${returnUtil}.SUCCESS("保存成功");
}
/**
@@ -58,9 +58,9 @@ public class ${classInfo.className}Controller {
${classInfo.className} ${classInfo.className?uncap_first} = ${classInfo.className?uncap_first}Mapper.selectOne(new QueryWrapper<${classInfo.className}>().eq("${classInfo.className?uncap_first}_id",id));
if(${classInfo.className?uncap_first}!=null){
${classInfo.className?uncap_first}Mapper.deleteById(id);
return new ReturnT<>(ReturnT.SUCCESS_CODE,"删除成功");
return ${returnUtil}.SUCCESS("删除成功");
}else{
return new ReturnT<>(ReturnT.FAIL_CODE,"没有找到该对象");
return ${returnUtil}.ERROR("没有找到该对象");
}
}
@@ -71,14 +71,14 @@ public class ${classInfo.className}Controller {
public Object find(int id){
${classInfo.className} ${classInfo.className?uncap_first} = ${classInfo.className?uncap_first}Mapper.selectOne(new QueryWrapper<${classInfo.className}>().eq("${classInfo.className?uncap_first}_id",id));
if(${classInfo.className?uncap_first}!=null){
return new ReturnT<>(${classInfo.className?uncap_first});
return ${returnUtil}.SUCCESS(${classInfo.className?uncap_first});
}else{
return new ReturnT<>(ReturnT.FAIL_CODE,"没有找到该对象");
return ${returnUtil}.ERROR("没有找到该对象");
}
}
/**
* 分页查询
* 自动分页查询
*/
@PostMapping("/list")
public Object list(String searchParams,
@@ -96,17 +96,57 @@ public class ${classInfo.className}Controller {
//执行分页
IPage<${classInfo.className}> pageList = ${classInfo.className?uncap_first}Mapper.selectPage(buildPage, queryWrapper);
//返回结果
return new ReturnT<>(pageList.getRecords(),Integer.parseInt(pageList.getTotal()+""));
return ${returnUtil}.PAGE(pageList.getRecords(),pageList.getTotal());
}
/**
* 手工分页查询(按需使用)
*/
@PostMapping("/list2")
public ReturnT list2(String searchParams,
@RequestParam(required = false, defaultValue = "0") int page,
@RequestParam(required = false, defaultValue = "10") int limit) {
log.info("searchParams:"+ JSON.toJSONString(searchParams));
//通用模式
${classInfo.className} queryParamDTO = JSON.parseObject(searchParams, ${classInfo.className}.class);
//专用DTO模式
//QueryParamDTO queryParamDTO = JSON.parseObject(searchParams, QueryParamDTO.class);
//queryParamDTO.setPage((page - 1)* limit);
//queryParamDTO.setLimit(limit);
//(page - 1) * limit, limit
List<${classInfo.className}> itemList = ${classInfo.className?uncap_first}Mapper.pageAll(queryParamDTO,(page - 1)* limit,limit);
Integer itemCount = ${classInfo.className?uncap_first}Mapper.countAll(queryParamDTO);
//返回结果
return ReturnT.PAGE(itemList,itemCount);
}
@GetMapping("/list")
public ModelAndView listPage(){
return new ModelAndView("cms/${classInfo.className?uncap_first}-list");
}
@GetMapping("/edit")
public ModelAndView editPage(int id){
${classInfo.className} ${classInfo.className?uncap_first} = ${classInfo.className?uncap_first}Mapper.selectOne(new QueryWrapper<${classInfo.className}>().eq("${classInfo.className?uncap_first}_id",id));
return new ModelAndView("cms/${classInfo.className?uncap_first}-edit","${classInfo.className?uncap_first}",${classInfo.className?uncap_first});
}
/**
* 发布/暂停(如不需要请屏蔽)
*/
@PostMapping("/publish")
public Object publish(int id,Integer status){
${classInfo.className} ${classInfo.className?uncap_first} = ${classInfo.className?uncap_first}Mapper.selectOne(new QueryWrapper<${classInfo.className}>().eq("${classInfo.className?uncap_first}_id",id));
if(${classInfo.className?uncap_first}!=null){
${classInfo.className?uncap_first}.setUpdateTime(new Date());
${classInfo.className?uncap_first}.setStatus(status);
${classInfo.className?uncap_first}Mapper.updateById(${classInfo.className?uncap_first});
return ReturnT.SUCCESS((status==1)?"已发布":"已暂停");
}else if(status.equals(${classInfo.className?uncap_first}.getStatus())){
return ReturnT.SUCCESS("状态不正确");
}else{
return ReturnT.ERROR();
}
}
}

View File

@@ -10,7 +10,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
/**
* @description ${classInfo.classComment}
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd HH:mm:ss')}
* @date ${.now?string('yyyy-MM-dd')}
*/
@Data<#if swagger?exists && swagger==true>
@ApiModel("${classInfo.classComment}")</#if>

View File

@@ -4,11 +4,12 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import ${packageName}.entity.${classInfo.className};
import java.util.List;
/**
* @description ${classInfo.classComment}
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd HH:mm:ss')}
* @date ${.now?string('yyyy-MM-dd')}
*/
@Mapper
public interface ${classInfo.className}Mapper extends BaseMapper<${classInfo.className}> {
@@ -23,7 +24,7 @@ public interface ${classInfo.className}Mapper extends BaseMapper<${classInfo.cla
//add here if need page limit
//" limit ¥{page},¥{limit} " +
" </script>")
List<${classInfo.className}> pageAll(${classInfo.className} queryParamDTO);
List<${classInfo.className}> pageAll(${classInfo.className} queryParamDTO,int page,int limit);
@Select("<script>select count(1) from ${classInfo.tableName} t0 " +
//add here if need left join

View File

@@ -11,7 +11,7 @@ import java.util.Map;
/**
* @description ${classInfo.classComment}
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd HH:mm:ss')}
* @date ${.now?string('yyyy-MM-dd')}
*/
@RestController
@RequestMapping(value = "/${classInfo.className}")

View File

@@ -6,7 +6,7 @@ import java.util.List;
/**
* @description ${classInfo.classComment}
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd HH:mm:ss')}
* @date ${.now?string('yyyy-MM-dd')}
*/
@Mapper
@Repository

View File

@@ -7,7 +7,7 @@ import java.util.List;
/**
* @description ${classInfo.classComment}Mapper
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd HH:mm:ss')}
* @date ${.now?string('yyyy-MM-dd')}
*/
@Mapper
@Repository

View File

@@ -5,7 +5,7 @@ import java.util.List;
/**
* @description ${classInfo.classComment}
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd HH:mm:ss')}
* @date ${.now?string('yyyy-MM-dd')}
*/
public class ${classInfo.className} implements Serializable {

View File

@@ -3,7 +3,7 @@ import java.util.Map;
/**
* @description ${classInfo.classComment}
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd HH:mm:ss')}
* @date ${.now?string('yyyy-MM-dd')}
*/
public interface ${classInfo.className}Service {

View File

@@ -9,7 +9,7 @@ import java.util.Map;
/**
* @description ${classInfo.classComment}
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd HH:mm:ss')}
* @date ${.now?string('yyyy-MM-dd')}
*/
@Service
public class ${classInfo.className}ServiceImpl implements ${classInfo.className}Service {
@@ -23,25 +23,25 @@ public class ${classInfo.className}ServiceImpl implements ${classInfo.className}
// valid
if (${classInfo.className?uncap_first} == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "必要参数缺失");
return ${returnUtil}.ERROR("必要参数缺失");
}
${classInfo.className?uncap_first}Mapper.insert(${classInfo.className?uncap_first});
return ReturnT.SUCCESS;
return ${returnUtil}.SUCCESS;
}
@Override
public ReturnT<String> delete(int id) {
int ret = ${classInfo.className?uncap_first}Mapper.delete(id);
return ret>0?ReturnT.SUCCESS:ReturnT.FAIL;
return ret>0?${returnUtil}.SUCCESS():${returnUtil}.ERROR();
}
@Override
public ReturnT<String> update(${classInfo.className} ${classInfo.className?uncap_first}) {
int ret = ${classInfo.className?uncap_first}Mapper.update(${classInfo.className?uncap_first});
return ret>0?ReturnT.SUCCESS:ReturnT.FAIL;
return ret>0?${returnUtil}.SUCCESS():${returnUtil}.ERROR();
}

View File

@@ -24,7 +24,7 @@
<div class="layui-form-item">
<label class="layui-form-label required">${fieldItem.fieldComment}</label>
<div class="layui-input-block">
<input type="text" name="${fieldItem.fieldName}" lay-verify="required" lay-reqtext="${fieldItem.fieldComment}不能为空" placeholder="请输入${fieldItem.fieldComment}" value="" class="layui-input">
<input type="text" name="${fieldItem.fieldName}" lay-verify="required" lay-reqtext="${fieldItem.fieldComment}不能为空" placeholder="请输入${fieldItem.fieldComment}" value="¥{(${classInfo.className?uncap_first}.${fieldItem.fieldName})!!}" class="layui-input">
<#--<tip>${fieldItem.fieldComment}</tip>-->
</div>
</div>

View File

@@ -40,8 +40,8 @@
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm data-add-btn"> 添加${classInfo.classComment} </button>
<#-- <button class="layui-btn layui-btn-sm layui-btn-danger data-delete-btn"> 删除${classInfo.classComment} </button>-->
<button class="layui-btn layui-btn-normal layui-btn-sm data-add-btn" lay-event="add"> <i class="layui-icon layui-icon-addition"></i>${classInfo.classComment} </button>
<#-- <button class="layui-btn layui-btn-normal layui-btn-sm layui-btn-danger data-delete-btn" lay-event="del"> 删除${classInfo.classComment} </button>-->
</div>
</script>
@@ -52,11 +52,20 @@
<a class="layui-btn layui-btn-xs layui-btn-danger data-count-delete" lay-event="delete">删除</a>
</script>
<script type="text/html" id="statusTemplate">
{{# if(d.status = 1){ }}
启用
<script type="text/html" id="typeTemplate">
{{# if(d.type == '1'){ }}
常规
{{# } else if(d.type =='2') { }}
专项
{{# } else { }}
停用
其它
{{# } }}
</script>
<script type="text/html" id="statusTemplate">
{{# if(d.status == '1' ){ }}
<i class="layui-icon layui-icon-ok"></i>已发布
{{# } else { }}
- 未发布
{{# } }}
</script>
</div>
@@ -66,8 +75,7 @@
layui.use(['form', 'table'], function () {
var $ = layui.jquery,
form = layui.form,
table = layui.table,
layuimini = layui.layuimini;
table = layui.table;
table.render({
elem: '#currentTableId',
@@ -83,23 +91,26 @@
{type: "checkbox", width: 50, fixed: "left"},
<#if classInfo.fieldList?exists && classInfo.fieldList?size gt 0>
<#list classInfo.fieldList as fieldItem >
{field: '${fieldItem.fieldName}', width: 150, title: '${fieldItem.fieldComment}', sort: true}, <#if fieldItem_has_next> </#if>
{field: '${fieldItem.fieldName}', title: '${fieldItem.fieldComment}', sort: true}, <#if fieldItem_has_next> </#if>
</#list>
</#if>
{title: '操作', minWidth: 50, templet: '#currentTableBar', fixed: "right", align: "center"}
/* 需要时间请自行解封
{title: '创建时间', sort: true,templet: "<div>{{layui.util.toDateString(d.createTime, 'yyyy-MM-dd')}}</div>"},
{title: '修改时间', sort: true,templet: "<div>{{layui.util.toDateString(d.updateTime, 'yyyy-MM-dd')}}</div>"},
*/
{title: '操作', minWidth: 400, templet: '#currentTableBar', fixed: "right", align: "center"}
]],
limits: [10, 20, 50 , 100],
limit: 10,
limits: [20 , 50 , 100],
limit: 20,
page: true
});
var result;
// 监听搜索操作
/**
* submit(data-search-btn):监听搜索操作
*/
form.on('submit(data-search-btn)', function (data) {
result = JSON.stringify(data.field);
// layer.alert(result, {
// title: '最终的搜索信息'
// });
//执行搜索重载
table.reload('currentTableId', {
@@ -113,51 +124,54 @@
return false;
});
var searchBtn = $("#searchBtn");
// 监听添加操作
$(".data-add-btn").on("click", function () {
var index = layer.open({
title: '添加${classInfo.classComment}',
type: 2,
shade: 0.2,
maxmin:true,
shadeClose: true,
area: ['800px', '500px'],
content: '¥{request.contextPath}/${classInfo.className?uncap_first}/edit?id=0',
});
layer.full(index);
return false;
});
// 监听删除操作
$(".data-delete-btn").on("click", function () {
var checkStatus = table.checkStatus('currentTableId')
, data = checkStatus.data;
layer.alert(JSON.stringify(data));
});
//监听表格复选框选择
table.on('checkbox(currentTableFilter)', function (obj) {
console.log(obj)
});
//监听表格编辑删除等功能按钮
table.on('tool(currentTableFilter)', function (obj) {
var data = obj.data;
if (obj.event === 'edit') {
/**
* toolbar监听事件:表格添加按钮
*/
table.on('toolbar(currentTableFilter)', function (obj) {
if (obj.event === 'add') {
var index = layer.open({
title: '编辑${classInfo.classComment}',
title: '添加',
type: 2,
shade: 0.2,
maxmin:true,
shadeClose: true,
area: ['800px', '500px'],
area: ['1000px', '700px'],
content: '¥{request.contextPath}/${classInfo.className?uncap_first}/edit?id=0',
});
return false;
}else if(obj.event === 'del') {
var checkStatus = table.checkStatus('currentTableId')
, data = checkStatus.data;
layer.alert(JSON.stringify(data));
}
});
/**
* checkbox(currentTableFilter):表格复选框选择
*/
table.on('checkbox(currentTableFilter)', function (obj) {
//console.log(obj)
});
/**
* tool监听事件:表格编辑删除等功能按钮
*/
table.on('tool(currentTableFilter)', function (obj) {
var data = obj.data;
if (obj.event === 'edit') {
var index = layer.open({
title: '编辑',
type: 2,
shade: 0.2,
maxmin:true,
shadeClose: true,
area: ['1000px', '700px'],
content: '¥{request.contextPath}/${classInfo.className?uncap_first}/edit?id='+obj.data.${classInfo.className?uncap_first}Id,
});
layer.full(index);
return false;
} else if (obj.event === 'delete') {
layer.confirm('真的删除行么', function (index) {
layer.confirm('确认删除该记录吗?', function (index) {
$.ajax({
type: 'POST',
url: "¥{request.contextPath}/${classInfo.className?uncap_first}/delete",
@@ -169,13 +183,40 @@
});
} else {
layer.msg(responseData.msg, function () {
//window.location = '/index.html';
});
}
}
});
layer.close(index);
});
}else if (obj.event === 'publish') {
layer.confirm('确定要发布吗?', function (index) {
$.ajax({
type: 'POST',
url: "¥{request.contextPath}/${classInfo.className?uncap_first}/publish",
data:{"id":obj.data.${classInfo.className?uncap_first}Id,"status":"1"},
success: function (responseData) {
searchBtn.click();
layer.msg(responseData.msg, function () {
});
}
});
layer.close(index);
});
}else if (obj.event === 'unpublish') {
layer.confirm('确定要停止吗?', function (index) {
$.ajax({
type: 'POST',
url: "¥{request.contextPath}/${classInfo.className?uncap_first}/publish",
data:{"id":obj.data.${classInfo.className?uncap_first}Id,"status":"0"},
success: function (responseData) {
searchBtn.click();
layer.msg(responseData.msg, function () {
});
}
});
layer.close(index);
});
}
});

View File

@@ -229,11 +229,11 @@
<div class="input-group-prepend">
<span class="input-group-text">作者名称</span>
</div>
<input type="text" class="form-control" id="authorName" name="authorName" value="大狼狗">
<input type="text" class="form-control" id="authorName" name="authorName" value="zhengkai.blog.csdn.net">
<div class="input-group-prepend">
<span class="input-group-text">返回封装</span>
</div>
<input type="text" class="form-control" id="returnUtil" name="returnUtil" value="new ReturnT<>">
<input type="text" class="form-control" id="returnUtil" name="returnUtil" value="ReturnT">
<div class="input-group-prepend">
<span class="input-group-text">包名路径</span>
</div>
@@ -245,9 +245,10 @@
</div>
<select type="text" class="form-control" id="dataType"
name="dataType">
<option value="sql">sql</option>
<option value="sql">ddl-sql</option>
<option value="json">json</option>
<option value="sql-regex">sql-regex</option>
<option value="insert-sql">insert-sql</option>
<#--<option value="sql-regex">sql-regex</option>-->
</select>
<div class="input-group-prepend">
<span class="input-group-text">tinyint转换类型</span>