38 Commits

Author SHA1 Message Date
MOSHOW.K.ZHENG
271087331f default_encoding: UTF-8 2020-06-21 22:35:13 +08:00
MOSHOW.K.ZHENG
82f9ef9624 default_encoding: UTF-8 2020-06-21 21:37:46 +08:00
MOSHOW.K.ZHENG
0ed4d7ace6 修复FreemarkerUtil的Path问题导致JAR包运行时无法获取template的问题。 2020-06-21 21:29:03 +08:00
MOSHOW.K.ZHENG
83f15b4034 1.一些fix,关于封装工具类以及layui模板优化等.<br> 2.优化表备注的获取逻辑.<br> 3.生成时间格式改为yyyy-MM-dd,移除具体的时间,只保留日期 2020-05-25 21:44:46 +08:00
MOSHOW.K.ZHENG
a4f72c80dd update README.md 2020-05-24 21:17:40 +08:00
moshowgame
6c0e5764d4 新增insert-sql模式,支持对"insert into table (xxx) values (xxx)"语句进行处理,生成java代码(感谢三叔的建议) 2020-05-22 00:50:54 +08:00
moshowgame
b30ce868ff 新增mapper2(Mybatis-Annotation模板)(感谢@baisi525和@CHKEGit的建议) 2020-05-18 00:18:36 +08:00
moshowgame
e90f9f77e4 赞赏优化 2020-05-17 22:49:30 +08:00
moshowgame
e97c6c1d88 修复包含comment关键字时注释无法识别的问题。(感谢@1nchaos的反馈) 2020-05-17 22:21:33 +08:00
moshowgame
808da25d4b 新增对Jrebel配置文件的排除 - MOSHOW K ZHENG 2020-05-17 01:14:03 +08:00
moshowgame
0341e53276 代码重构!异常处理优化,Freemarker相关工具类优化,简化模板生成部分,通过template.json来配置需要生成的模板,不需要配置java文件。 2020-05-17 01:07:15 +08:00
Moshow郑锴
6149d9916d Merge pull request #83 from gaohanghang/master
1. 通过 InetAddress 类动态获取主机的ip地址 2. 折叠 catch 块
2020-05-13 19:44:40 +08:00
gaohanghang
f8b598dd89 将"项目启动启动成功"改为"项目启动成功" 2020-05-07 20:07:23 +08:00
gaohanghang
06e05abd6f 1. 通过InetAddress类动态获取主机的ip地址 2. 折叠 catch 块 2020-05-07 20:00:36 +08:00
gaohang
3316c98326 Merge pull request #8 from moshowgame/master
merge
2020-05-07 19:35:42 +08:00
MOSHOW.K.ZHENG
77748195dd 20200503:1.优化对特殊字符的处理,对于包含#和$等特殊字符的,在模板使用井和¥代替便可,escapeString方法会自动处理<br> 2.优化mybatisplus实体类相关(感谢@chunchengmeigui的反馈) 3.修优化对所有类型的判断(感谢@cnlw的反馈) 4.移除swagger-entity,该功能已经包含在‘swagger-ui’的下拉选项中 5.升级hutool和lombok版本 2020-05-03 21:08:14 +08:00
MOSHOW.K.ZHENG
0dea9b5ac0 Merge remote-tracking branch 'origin/master' 2020-05-03 19:49:20 +08:00
Moshow郑锴
3232e0f082 LICENSE
LICENSE
2020-03-15 00:40:51 +08:00
MOSHOW.K.ZHENG
45484d8949 20200306提交一套layuimini+mybatisplus的模板.修复mybatisplus一些相关问题 2020-03-06 23:16:09 +08:00
gaohang
9b6562b773 Merge pull request #7 from moshowgame/master
merge
2020-02-22 00:02:43 +08:00
Moshow郑锴
e78f38e3c9 去除mybatis模板中的方括号[]和修改模板里的类注释样式(感谢@gaohanghang的PR)
去除mybatis模板中的方括号[]和修改模板里的类注释样式(感谢@gaohanghang的PR)
2020-02-05 21:52:23 +08:00
Moshow郑锴
c94e0048ab Merge pull request #78 from gaohanghang/master
去除 mybatis 模板中的方括号[]、修改模板里的类注释样式(感谢@gaohanghang的PR)
2020-02-05 21:51:23 +08:00
MOSHOW.K.ZHENG
2316fb1780 1.新增历史记录功能,自动保存最近生成的对象 2.新增swagger开关选项和修复@Column带name参数(感谢@liuyu-struggle的建议)
1.新增历史记录功能,自动保存最近生成的对象 2.新增swagger开关选项和修复@Column带name参数(感谢@liuyu-struggle的建议)
2020-02-05 21:44:07 +08:00
gaohanghang
90750d420f 1. 去除 mybatis 模板中的方括号[],使代码更美观
2. 修改模板里的类注释样式,使注释更规范
2020-01-14 22:54:18 +08:00
gaohang
11ad5535e3 Merge pull request #6 from moshowgame/master
merge
2020-01-14 22:24:50 +08:00
MOSHOW.K.ZHENG
03152e54ef 1.修复bejson安全防护策略拦截问题(感谢@liangbintao和@1808083642的反馈) 2.优化字段名含date字符串的处理(感谢@smilexzh的反馈) 3.控制台动态输出项目访问地址(感谢@gaohanghang的提交) 2019-12-29 22:51:19 +08:00
Moshow郑锴
8b37443018 Merge pull request #73 from gaohanghang/master
动态获取tomcat启动端口,控制台打印项目访问地址(PR by @gaohanghang )
2019-12-29 22:40:20 +08:00
gaohanghang
eb7760ac18 动态获取tomcat启动端口,控制台打印项目访问地址 2019-12-27 14:43:49 +08:00
gaohang
ae7815105f Merge pull request #5 from moshowgame/master
merge
2019-11-29 20:19:56 +08:00
MOSHOW.K.ZHENG
b7861ca9fc version 2019-11-28 23:26:31 +08:00
MOSHOW.K.ZHENG
870d95e1bf version 2019-11-28 23:16:09 +08:00
MOSHOW.K.ZHENG
a84a4c1087 1.修复支持string-copy导致的以n结尾的字母不显示问题 2.jpa-entity新增swagger@ApiModel@ApiModelProperty注解和SQL字段@Column注解(感谢@yjq907的建议) 2019-11-28 22:19:53 +08:00
Moshow郑锴
f746461188 Merge pull request #60 from gaohanghang/master
更新实体类模板,将 serialVersionUID 所在行的代码换行,使代码更加美观
2019-11-26 23:06:14 +08:00
MOSHOW.K.ZHENG
02c43a8a9e Update README.md 2019-11-26 22:58:24 +08:00
MOSHOW.K.ZHENG
f45b1bfa8a add release jar download url&img
add release jar download url&img
2019-11-26 22:56:20 +08:00
gaohanghang
6cfa5d2c63 更新实体类模板,将 serialVersionUID 所在行的代码换行,使代码更加美观 2019-11-25 02:16:36 +08:00
gaohang
a4736f65b5 Merge pull request #4 from moshowgame/master
merge
2019-11-25 01:51:01 +08:00
gaohang
60b214bf0f Merge pull request #3 from moshowgame/master
merge
2019-11-15 00:04:39 +08:00
47 changed files with 2151 additions and 1305 deletions

3
.gitignore vendored
View File

@@ -198,4 +198,7 @@ buildNumber.properties
.mvn/timing.properties .mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar .mvn/wrapper/maven-wrapper.jar
#rebel
rebel.xml
rebel-remote.xml
# End of https://www.gitignore.io/api/java,maven,eclipse,java-web,intellij+all # End of https://www.gitignore.io/api/java,maven,eclipse,java-web,intellij+all

21
LICENSE.txt Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Moshow K ZHENG(Moshow/郑锴/大狼狗)
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:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
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.

180
README.md
View File

@@ -1,79 +1,101 @@
# SpringBootCodeGenerator # 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/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-brightgreen.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-brightgreen.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) [![Build Status](https://travis-ci.org/moshowgame/SpringBootCodeGenerator.svg?branch=master)](https://travis-ci.org/moshowgame/SpringBootCodeGenerator)
# Description # Description
- √ 基于SpringBoot2+Freemarker+Bootstrap - √ 基于SpringBoot2+Freemarker+Bootstrap
- √ 以放双手为目的 - √ 以放双手为目的减少大量重复的CRUD工作
- √ 支持mysql/oracle/pgsql三大数据库 - √ 支持mysql/oracle/pgsql三大数据库
- √ 用DDL-SQL语句生成JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL相关代码. - √ 用DDL-SQL语句生成JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL相关代码.
# Advantage
# Url - 支持DDL SQL/INSERT SQL/SIMPLE JSON生成模式
- 自动记忆最近生成的内容最多保留9个
|访问路径|http://localhost:1234/generator| - 提供众多通用模板易于使用复制粘贴加简单修改即可完成CRUD操作
|-|-| - 支持特殊字符模板(`#`请用`井`代替;`$`请用`¥`代替)
|在线地址|http://java.bejson.com/generator| - 根据comment=(mysql)或者comment on table(pgsql/oracle)生成类名注释
|CSDN博客|http://zhengkai.blog.csdn.net|
# Url
感谢bejson三叔将他部署在[BEJSON](www.bejson.com)上目前是besjon专供工具(线上版本不一定是最新的,会有延迟,请谅解,谢谢).
|访问路径|http://localhost:1234/generator|
|----|----|
# Update |在线地址|http://java.bejson.com/generator|
|CSDN博客|http://zhengkai.blog.csdn.net|
|更新日期|更新内容| |最新Jar包|https://github.com/moshowgame/SpringBootCodeGenerator/releases|
|-|-|
|20191126|1.springboot2内置tomcat更换为性能更强大的undertow 2.修复tinyintTransType参数丢失问题 | 感谢bejson三叔将他部署在[BEJSON](www.bejson.com)上目前是besjon专供的金牌工具(线上版本不一定是最新的,会有延迟,请谅解,谢谢).
|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的反馈). | # Update
|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依赖减少打包体积. | |20200621|修复FreemarkerUtil的Path问题导致JAR包运行时无法获取template的问题。|
|20190910-1|1.修复mapper接口load方法但是xml中方法不匹配问题 2.移除mapper中CRUD时的@param 注解会影响xml的解析(感谢@caojiantao的反馈).3.优化MyBatis的xml文件对Oracle的支持.(感谢@wylove1992的反馈) 4.新增对boolean的处理(感谢@violinxsc的反馈)以及优化tinyint类型生成boolean类型问题(感谢@hahaYhui的反馈) | |20200525|1.一些fix,关于封装工具类以及layui模板优化等.<br> 2.优化表备注的获取逻辑.<br> 3.生成时间格式改为yyyy-MM-dd,移除具体的时间,只保留日期|
|20190909|添加是否下划线转换为驼峰的选择(感谢@youngking28 的pull request).| |20200522|1.新增insert-sql模式,支持对"insert into table (xxx) values (xxx)"语句进行处理,生成java代码(感谢三叔的建议).|
|20190518|1.优化注释 2.修改 mybatis模板中 controller注解 3.修改 mybatis模板中 dao文件使用为 mapper文件 4.修改 mybatis模板中 service实现类中的一个 bug 5.修改 index.ftl文件中 mybatis模板的 dao -> mapper(感谢@unqin的pull request)| |20200517|1.代码重构!异常处理优化,Freemarker相关工具类优化,简化模板生成部分,通过template.json来配置需要生成的模板,不需要配置java文件.<br> 2.修复包含comment关键字时注释无法识别的问题.(感谢@1nchaos的反馈).<br> 3.赞赏优化,感谢大家的赞赏.<br> 4.新增mapper2(Mybatis-Annotation模板)(感谢@baisi525和@CHKEGit的建议).|
|20190511|优化mybatis模块的dao和xml模板修改dao接口注解为@Repository所有dao参数改为包装类删除update语句最后的UpdateTime = NOW()修改dao接口文件的方法注释使其更符合javaDoc的标准修改insert语句增加插入行主键的返回修改load的方法名为selectByPrimaryKey修改xml的update语句新增动态if判空修改xml的insert语句新增动态插入判空更符合mybatisGenerator标准(感谢@Archer-Wen的贡献 ).| |20200503|1.优化对特殊字符的处理,对于包含#和$等特殊字符的,在模板使用井和¥代替便可,escapeString方法会自动处理.<br> 2.优化mybatisplus实体类相关(感谢@chunchengmeigui的反馈).<br> 3.修优化对所有类型的判断(感谢@cnlw的反馈).<br> 4.移除swagger-entity,该功能已经包含在swagger-ui的下拉选项中 <br> 5.升级hutool和lombok版本|
|20190429|新增返回封装工具类设置优化对oracle注释comment on column的支持(感谢@liukex反馈)优化对普通和特殊storage关键字的判断(感谢@AhHeadFloating的反馈 ).| |20200306|1.提交一套layuimini+mybatisplus的模板.<br> 2.修复mybatisplus一些相关问题. |
|20190211|提交gitignore解决StringUtils.lowerCaseFirst潜在的NPE异常校验修改为@RequestParam参数校验lombok之@Data和@Slf4j优化fix JdbcDAO模板类名显示为中文问题WebMvcConfig整合MessageConverter模板代码分类(感谢@liutf和@tfgzs的pull request).| |20200206|1.新增历史记录功能,自动保存最近生成的对象.<br> 2.新增swagger开关选项和修复@Column带name参数(感谢@liuyu-struggle的建议).<br> 3.去除mybatis模板中的方括号[]和修改模板里的类注释样式(感谢@gaohanghang的PR)|
|20190210|实体生成规则切换为包装类型,不再采用基本数据类型,为实体类生成添加显示的默认构造方法(感谢@h2so的pull request).| |20191229|1.修复bejson安全防护策略拦截问题(感谢@liangbintao和@1808083642的反馈).<br> 2.优化字段名含date字符串的处理(感谢@smilexzh的反馈).<br> 3.控制台动态输出项目访问地址(感谢@gaohanghang的提交)|
|20190106|修复处理number/decimal(x,x)类型的逻辑(感谢@arthaschan的反馈)修复JdbcTemplates模板两处错误(感谢@everflourish的反馈).| |20191128|1.修复支持string-copy导致的以n结尾的字母不显示问题.<br> 2.jpa-entity新增swagger@ApiModel@ApiModelProperty注解和SQL字段@Column注解(感谢@yjq907的建议) |
|20181212|首页UI优化新增MybatisPlus模块(感谢@三叔同事的建议),修复作者名和包名获取失败问题(感谢@Yanch1994的反馈).| |20191126|1.springboot2内置tomcat更换为性能更强大的undertow.<br> 2.修复tinyintTransType参数丢失问题 |
|20181122|优化正则表达式点号的处理优化处理字段类型对number类型增加intlongBigDecimal的区分判断(感谢@lshz0088的指导).| |20191124|1.java代码结构优化.<br> 2.新增简单的json生成模式.<br> 3.新增简单的正则表达式匹配模式(感谢@ydq的贡献).<br> 4.新增对复制String代码中的乱SQL代码的支持 5.优化对JSON的父子节点/处理,JSONObject和JSONArray节点处理,子节点缺失'{'头处理|
|20181108|修复非字段描述"KEY FK_xxxx (xxxx)"导致生成KEY字段情况(感谢@tornadoorz反馈).| |20191123|1.移除频繁出错和被过滤的layer,改为jquery-toast.<br> 2.Util功能优化,新增json和xml.|
|20181018|支持double(x,x)的类型以及comment里面包含一些特殊字符的处理(感谢@tanwubo的反馈).| |20191116|优化对primary关键字的处理(感谢@liujiansgit的反馈). |
|20181010|CDN变更修复CDN不稳定导致网页js报错问题.| |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.其他一些优化. |
|20181003|新增element-ui/bootstrap生成.| |20191015|修复jdbcTemplates中insert语句第一个字段丢失的问题. |
|20181002|修复公共CDN之Layer.js404问题导致项目无法生成.| |20190915|1.添加对象getset模板.<br> 2.添加sql模板.<br> 3.启动类添加日志输出,方便项目使用(感谢@gaohanghang 的pull request) |
|20180927|优化COMMENT提取逻辑支持多种复杂情况的注释(感谢@raodeming的反馈).| |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的反馈) |
|20180926|全新BeetlSQL模块以及一些小细节优化(感谢@三叔同事的建议).| |20190909|添加是否下划线转换为驼峰的选择(感谢@youngking28 的pull request).|
|20180925|优化SQL表和字段备注的推断包括pgsql/oralce的comment on column/table情况处理等.| |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)|
|20180918|优化SQL类型推断.优化PrimaryKey判断.修复jpacontroller中Repository拼写错误问题.| |20190511|优化mybatis模块的dao和xml模板,修改dao接口注解为@Repository,所有dao参数改为包装类,删除update语句最后的UpdateTime = NOW(),修改dao接口文件的方法注释使其更符合javaDoc的标准,修改insert语句增加插入行主键的返回,修改load的方法名为selectByPrimaryKey,修改xml的update语句新增动态if判空,修改xml的insert语句新增动态插入判空,更符合mybatisGenerator标准(感谢@Archer-Wen的贡献 ).|
|20180917|全新首页静态文件全部采用CDN.新增jdbcTemplate模块.| |20190429|新增返回封装工具类设置.<br> 优化对oracle注释comment on column的支持(感谢@liukex反馈).<br> 优化对普通和特殊storage关键字的判断(感谢@AhHeadFloating的反馈 ).|
|20180916|1.优化oracle支持优化DDL语句中"或者'或者空格的支持. 2.补充char/clob/blob/json等类型如果类型未知默认为String.| |20190211|提交gitignore,解决StringUtils.lowerCaseFirst潜在的NPE异常,校验修改为@RequestParam参数校验,lombok之@Data和@Slf4j优化,fix JdbcDAO模板类名显示为中文问题,WebMvcConfig整合MessageConverter,模板代码分类(感谢@liutf和@tfgzs的pull request).|
|20180915|新增Swagger-UI模板.修复一些命名和导入问题.JPA的Entity默认第一个字段为Id如果不是请手工修改.| |20190210|实体生成规则切换为包装类型,不再采用基本数据类型,为实体类生成添加显示的默认构造方法(感谢@h2so的pull request).|
|20180913|修复字段没有描述以及类型为DATE型导致的问题.新增JPA的Controller模板.| |20190106|修复处理number/decimal(x,x)类型的逻辑(感谢@arthaschan的反馈).<br> 修复JdbcTemplates模板两处错误(感谢@everflourish的反馈).|
|20180831|初始化项目.新增JPA系列Entity+Repository模板.| |20181212|首页UI优化.<br> 新增MybatisPlus模块(感谢@三叔同事的建议).<br> 修复作者名和包名获取失败问题(感谢@Yanch1994的反馈).|
|20181122|优化正则表达式点号的处理,优化处理字段类型,对number类型增加int,long,BigDecimal的区分判断(感谢@lshz0088的指导).|
# FieldName |20181108|修复非字段描述"KEY FK_xxxx (xxxx)"导致生成KEY字段情况(感谢@tornadoorz反馈).|
|字段名|说明| |20181018|支持double(x,x)的类型,以及comment里面包含一些特殊字符的处理(感谢@tanwubo的反馈).|
|-|-| |20181010|CDN变更,修复CDN不稳定导致网页js报错问题.|
|packageName|自定义的包名| |20181003|新增element-ui/bootstrap生成.|
|authorName|自定义的作者名| |20181002|修复公共CDN之Layer.js404问题,导致项目无法生成.|
|returnUtil|自定义的返回Util| |20180927|优化COMMENT提取逻辑,支持多种复杂情况的注释(感谢@raodeming的反馈).|
|tableName|sql中的表名| |20180926|全新BeetlSQL模块,以及一些小细节优化(感谢@三叔同事的建议).|
|className|java类名| |20180925|优化SQL表和字段备注的推断,包括pgsql/oralce的comment on column/table情况处理等.|
|classComment|sql表备注/java类备注| |20180918|优化SQL类型推断.<br> 优化PrimaryKey判断.<br> 修复jpacontroller中Repository拼写错误问题.|
|fieldName|字段名| |20180917|全新首页,静态文件全部采用CDN.新增jdbcTemplate模块.|
|fieldComment|字段备注| |20180916|1.优化oracle支持,优化DDL语句中"或者'或者空格的支持.<br> 2.补充char/clob/blob/json等类型,如果类型未知,默认为String.|
|20180915|新增Swagger-UI模板.修复一些命名和导入问题.JPA的Entity默认第一个字段为Id,如果不是请手工修改.|
|20180913|修复字段没有描述以及类型为DATE型导致的问题.新增JPA的Controller模板.|
<img src="./codegenerator1.png"> |20180831|初始化项目.新增JPA系列Entity+Repository模板.|
<img src="./codegenerator2.png">
<img src="./codegenerator3.png"> # ClassInfo/TableInfo
<img src="./donate.jpg"> |字段名|说明|
|-|-|
|packageName|自定义的包名|
|authorName|自定义的作者名|
|returnUtil|自定义的返回Util|
|tableName|sql中的表名|
|className|java类名|
|classComment|sql表备注/java类备注|
|fieldName|字段名|
|fieldComment|字段备注|
# how to add a new template
1. code-generator中找到对应分类新增一个.ftl文件
2. 根据类信息编写freemarker模板.ftl文件
3. 修改template.json文件新增模板信息
4. index页面增加一个button
5. reload,test,complete
<img src="./codegenerator1.png">
<img src="./codegenerator2.png">
<img src="./codegenerator3.png">
<img src="./codegenerator4.png">
<img src="./donate.png">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 KiB

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 378 KiB

BIN
donate.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

View File

@@ -7,12 +7,12 @@
<parent> <parent>
<groupId>com.softdev.system</groupId> <groupId>com.softdev.system</groupId>
<artifactId>SpringBootCodeGenerator</artifactId> <artifactId>SpringBootCodeGenerator</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>2.0</version>
</parent> </parent>
<groupId>com.softdev.system</groupId> <groupId>com.softdev.system</groupId>
<artifactId>generator-web</artifactId> <artifactId>generator-web</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>2.0</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<properties> <properties>

View File

@@ -5,10 +5,8 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication @SpringBootApplication
@Slf4j
public class GeneratorWebApplication { public class GeneratorWebApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(GeneratorWebApplication.class,args); SpringApplication.run(GeneratorWebApplication.class,args);
log.info("项目启动启动成功!访问地址: http://localhost:1234/generator");
} }
} }

View File

@@ -1,20 +1,20 @@
package com.softdev.system.generator.config; package com.softdev.system.generator.config;
import javax.servlet.http.HttpServletRequest; import com.softdev.system.generator.entity.ReturnT;
import org.springframework.web.bind.annotation.ControllerAdvice;
import com.softdev.system.generator.entity.ReturnT; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest;
@ControllerAdvice @ControllerAdvice
public class GlobalDefaultExceptionHandler { public class GlobalDefaultExceptionHandler {
@ExceptionHandler(Exception.class) @ExceptionHandler(Exception.class)
@ResponseBody @ResponseBody
public ReturnT defaultExceptionHandler(HttpServletRequest req,Exception e) { public ReturnT defaultExceptionHandler(HttpServletRequest req,Exception e) {
e.printStackTrace(); e.printStackTrace();
return new ReturnT<>(ReturnT.FAIL_CODE, e.getMessage()); return ReturnT.ERROR(e.getMessage());
} }
} }

View File

@@ -0,0 +1,36 @@
package com.softdev.system.generator.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* @Description 通过实现ApplicationListener接口动态获取tomcat启动端口和访问路径通过InetAddress类获取主机的ip地址最后控制台打印项目访问地址
* @Author Gao Hang Hang
* @Date 2019-12-27 14:37
**/
@Component
@Slf4j
public class ServerConfig implements ApplicationListener<WebServerInitializedEvent> {
@Override
public void onApplicationEvent(WebServerInitializedEvent event) {
try {
InetAddress inetAddress = Inet4Address.getLocalHost();
// 主机ip地址
String hostAddress = inetAddress.getHostAddress();
// tomcat启动端口
int serverPort = event.getWebServer().getPort();
// 新增动态path by zhengkai
String serverPath = event.getApplicationContext().getApplicationName();
log.info("项目启动成功!访问地址: http://{}:{}{}", hostAddress, serverPort, serverPath);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}

View File

@@ -1,49 +1,49 @@
package com.softdev.system.generator.config; package com.softdev.system.generator.config;
import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.nio.charset.Charset; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* 2019-2-11 liutf WebMvcConfig 整合 cors 和 SpringMvc MessageConverter * 2019-2-11 liutf WebMvcConfig 整合 cors 和 SpringMvc MessageConverter
*/ */
@Configuration @Configuration
public class WebMvcConfig implements WebMvcConfigurer { public class WebMvcConfig implements WebMvcConfigurer {
/* @Override /* @Override
public void addCorsMappings(CorsRegistry registry) { public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") registry.addMapping("/**")
.allowedOrigins("*") .allowedOrigins("*")
.allowedHeaders("x-requested-with") .allowedHeaders("x-requested-with")
.allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "TRACE") .allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "TRACE")
.maxAge(3600); .maxAge(3600);
}*/ }*/
@Override @Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//FastJsonHttpMessageConverter //FastJsonHttpMessageConverter
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
List<MediaType> fastMediaTypes = new ArrayList<>(); List<MediaType> fastMediaTypes = new ArrayList<>();
fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8); fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
fastConverter.setSupportedMediaTypes(fastMediaTypes); fastConverter.setSupportedMediaTypes(fastMediaTypes);
FastJsonConfig fastJsonConfig = new FastJsonConfig(); FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setCharset(Charset.forName("UTF-8")); fastJsonConfig.setCharset(StandardCharsets.UTF_8);
fastConverter.setFastJsonConfig(fastJsonConfig); fastConverter.setFastJsonConfig(fastJsonConfig);
//StringHttpMessageConverter //StringHttpMessageConverter
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(); StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
stringConverter.setDefaultCharset(Charset.forName("UTF-8")); stringConverter.setDefaultCharset(StandardCharsets.UTF_8);
stringConverter.setSupportedMediaTypes(fastMediaTypes); stringConverter.setSupportedMediaTypes(fastMediaTypes);
converters.add(stringConverter); converters.add(stringConverter);
converters.add(fastConverter); converters.add(fastConverter);
} }
} }

View File

@@ -4,17 +4,15 @@ import com.softdev.system.generator.entity.ClassInfo;
import com.softdev.system.generator.entity.ParamInfo; import com.softdev.system.generator.entity.ParamInfo;
import com.softdev.system.generator.entity.ReturnT; import com.softdev.system.generator.entity.ReturnT;
import com.softdev.system.generator.service.GeneratorService; 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 com.softdev.system.generator.util.TableParseUtil;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -36,46 +34,41 @@ public class IndexController {
@PostMapping("/genCode") @PostMapping("/genCode")
@ResponseBody @ResponseBody
public ReturnT<Map<String, String>> codeGenerate( ParamInfo paramInfo ) { public ReturnT codeGenerate(@RequestBody ParamInfo paramInfo ) throws Exception {
try { if (paramInfo.getTableSql().trim().length()<1) {
return ReturnT.ERROR("表结构信息不可为空");
if (StringUtils.isBlank(paramInfo.getTableSql())) {
return new ReturnT<>(ReturnT.FAIL_CODE, "表结构信息不可为空");
}
// parse table
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;
}
// process the param
Map<String, Object> params = new HashMap<String, Object>(8);
params.put("classInfo", classInfo);
params.put("authorName", paramInfo.getAuthorName());
params.put("packageName", paramInfo.getPackageName());
params.put("returnUtil", paramInfo.getReturnUtil());
log.info("generator table:"+(classInfo==null?"":classInfo.getTableName()));
// generate the code 需要加新的模板请在里面改
Map<String, String> result = generatorService.getResultByParams(params);
return new ReturnT<>(result);
} catch (IOException | TemplateException e) {
log.error(e.getMessage(), e);
return new ReturnT<>(ReturnT.FAIL_CODE, e.getMessage());
} catch (CodeGenerateException e) {
log.error(e.getMessage(), e);
return new ReturnT<>(ReturnT.FAIL_CODE, e.getMessage());
} }
//1.Parse Table Structure 表结构解析
ClassInfo classInfo = null;
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
default : classInfo = TableParseUtil.processTableIntoClassInfo(paramInfo);break;
}
//2.Set the params 设置表格参数
Map<String, Object> params = new HashMap<String, Object>(8);
params.put("classInfo", classInfo);
params.put("tableName", classInfo==null?System.currentTimeMillis():classInfo.getTableName());
params.put("authorName", paramInfo.getAuthorName());
params.put("packageName", paramInfo.getPackageName());
params.put("returnUtil", paramInfo.getReturnUtil());
params.put("swagger", paramInfo.isSwagger());
//log the generated table and filed size记录解析了什么表有多少个字段
log.info("generated table:" + classInfo.getTableName() + ",field size:" + (classInfo.getFieldList() == null ? "" : classInfo.getFieldList().size()));
//3.generate the code by freemarker template and param . Freemarker根据参数和模板生成代码
Map<String, String> result = generatorService.getResultByParams(params);
return ReturnT.SUCCESS(result);
} }
} }

View File

@@ -1,25 +1,26 @@
package com.softdev.system.generator.entity; package com.softdev.system.generator.entity;
import lombok.Data; import lombok.Data;
/** /**
* Post data - ParamInfo * Post data - ParamInfo
* @author zhengkai.blog.csdn.net * @author zhengkai.blog.csdn.net
*/ */
@Data @Data
public class ParamInfo { public class ParamInfo {
private String tableSql; private String tableSql;
private String authorName; private String authorName;
private String packageName; private String packageName;
private String returnUtil; private String returnUtil;
private String nameCaseType; private String nameCaseType;
private String tinyintTransType; private String tinyintTransType;
private String dataType; private String dataType;
private boolean swagger;
@Data
public static class NAME_CASE_TYPE{ @Data
public static String CAMEL_CASE="CamelCase"; public static class NAME_CASE_TYPE{
public static String UNDER_SCORE_CASE="UnderScoreCase"; public static String CAMEL_CASE="CamelCase";
public static String UPPER_UNDER_SCORE_CASE="UpperUnderScoreCase"; public static String UNDER_SCORE_CASE="UnderScoreCase";
} public static String UPPER_UNDER_SCORE_CASE="UpperUnderScoreCase";
} }
}

View File

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

@@ -0,0 +1,18 @@
package com.softdev.system.generator.entity;
import lombok.Data;
import java.io.Serializable;
@Data
public class TemplateConfig implements Serializable {
public static final long serialVersionUID = 66L;
Integer id;
String name;
String group;
String path;
String description;
}

View File

@@ -1,17 +1,17 @@
package com.softdev.system.generator.service; package com.softdev.system.generator.service;
import freemarker.template.TemplateException; import freemarker.template.TemplateException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
/** /**
* GeneratorService * GeneratorService
* @author zhengkai.blog.csdn.net * @author zhengkai.blog.csdn.net
*/ */
public interface GeneratorService { public interface GeneratorService {
public Map<String,String> getResultByParams(Map<String, Object> params) throws IOException, TemplateException; public Map<String,String> getResultByParams(Map<String, Object> params) throws IOException, TemplateException;
} }

View File

@@ -1,78 +1,62 @@
package com.softdev.system.generator.service; package com.softdev.system.generator.service;
import com.softdev.system.generator.util.FreemarkerTool; import com.alibaba.fastjson.JSON;
import freemarker.template.TemplateException; import com.softdev.system.generator.entity.TemplateConfig;
import lombok.extern.slf4j.Slf4j; import com.softdev.system.generator.util.FreemarkerUtil;
import org.springframework.beans.factory.annotation.Autowired; import freemarker.template.TemplateException;
import org.springframework.stereotype.Service; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException; import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map; import java.io.BufferedReader;
import java.io.IOException;
/** import java.io.InputStream;
* GeneratorService import java.io.InputStreamReader;
* @author zhengkai.blog.csdn.net import java.util.LinkedHashMap;
*/ import java.util.List;
@Slf4j import java.util.Map;
@Service import java.util.stream.Collectors;
public class GeneratorServiceImpl implements GeneratorService {
/**
@Autowired * GeneratorService
private FreemarkerTool freemarkerTool; * @author zhengkai.blog.csdn.net
*/
@Override @Slf4j
public Map<String, String> getResultByParams(Map<String, Object> params) throws IOException, TemplateException { @Service
// result public class GeneratorServiceImpl implements GeneratorService {
Map<String, String> result = new HashMap<String, String>(32);
@Autowired
//UI private FreemarkerUtil freemarkerTool;
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)); String templateCpnfig=null;
result.put("bootstrap-ui", freemarkerTool.processString("code-generator/ui/bootstrap-ui.ftl", params)); /**
//mybatis old * 从项目中的JSON文件读取String
result.put("controller", freemarkerTool.processString("code-generator/mybatis/controller.ftl", params)); * @author zhengkai.blog.csdn.net
result.put("service", freemarkerTool.processString("code-generator/mybatis/service.ftl", params)); */
result.put("service_impl", freemarkerTool.processString("code-generator/mybatis/service_impl.ftl", params)); public String getTemplateConfig() throws IOException {
result.put("mapper", freemarkerTool.processString("code-generator/mybatis/mapper.ftl", params)); templateCpnfig=null;
result.put("mybatis", freemarkerTool.processString("code-generator/mybatis/mybatis.ftl", params)); if(templateCpnfig!=null){
result.put("model", freemarkerTool.processString("code-generator/mybatis/model.ftl", params)); }else{
//jpa InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template.json");
result.put("entity", freemarkerTool.processString("code-generator/jpa/entity.ftl", params)); templateCpnfig = new BufferedReader(new InputStreamReader(inputStream))
result.put("repository", freemarkerTool.processString("code-generator/jpa/repository.ftl", params)); .lines().collect(Collectors.joining(System.lineSeparator()));
result.put("jpacontroller", freemarkerTool.processString("code-generator/jpa/jpacontroller.ftl", params)); inputStream.close();
//jdbc template }
result.put("jtdao", freemarkerTool.processString("code-generator/jdbc-template/jtdao.ftl", params)); //log.info(JSON.toJSONString(templateCpnfig));
result.put("jtdaoimpl", freemarkerTool.processString("code-generator/jdbc-template/jtdaoimpl.ftl", params)); return templateCpnfig;
//beetsql }
result.put("beetlmd", freemarkerTool.processString("code-generator/beetlsql/beetlmd.ftl", params)); /**
result.put("beetlentity", freemarkerTool.processString("code-generator/beetlsql/beetlentity.ftl", params)); * 根据配置的Template模板进行遍历解析得到生成好的String
result.put("beetlentitydto", freemarkerTool.processString("code-generator/beetlsql/beetlentitydto.ftl", params)); * @author zhengkai.blog.csdn.net
result.put("beetlcontroller", freemarkerTool.processString("code-generator/beetlsql/beetlcontroller.ftl", params)); */
//mybatis plus @Override
result.put("pluscontroller", freemarkerTool.processString("code-generator/mybatis-plus/pluscontroller.ftl", params)); public Map<String, String> getResultByParams(Map<String, Object> params) throws IOException, TemplateException {
result.put("plusmapper", freemarkerTool.processString("code-generator/mybatis-plus/plusmapper.ftl", params)); Map<String, String> result = new LinkedHashMap<>(32);
//util result.put("tableName",params.get("tableName")+"");
result.put("util", freemarkerTool.processString("code-generator/util/util.ftl", params)); List<TemplateConfig> templateConfigList = JSON.parseArray(getTemplateConfig(),TemplateConfig.class);
result.put("json", freemarkerTool.processString("code-generator/util/json.ftl", params)); for (TemplateConfig item:templateConfigList){
result.put("xml", freemarkerTool.processString("code-generator/util/xml.ftl", params)); result.put(item.getName(), freemarkerTool.processString(item.getGroup()+"/"+item.getName()+".ftl", params));
//sql generate }
result.put("select", freemarkerTool.processString("code-generator/sql/select.ftl", params)); return result;
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<String, String> item: result.entrySet()) {
if (item.getValue() != null) {
lineNum += StringUtils.countMatches(item.getValue(), "\n");
}
}
log.info("生成代码行数:{}", lineNum);*/
//测试环境可自行开启
//log.info("生成代码数据:{}", result);
return result;
}
}

View File

@@ -1,59 +0,0 @@
package com.softdev.system.generator.util;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Map;
/**
* freemarker tool
*
* @author xuxueli 2018-05-02 19:56:00
*/
@Component
public class FreemarkerTool {
@Autowired
private Configuration configuration;
/**
* process Template Into String
*
* @param template
* @param model
* @return
* @throws IOException
* @throws TemplateException
*/
public String processTemplateIntoString(Template template, Object model)
throws IOException, TemplateException {
StringWriter result = new StringWriter();
template.process(model, result);
return result.toString();
}
/**
* process String
*
* @param templateName
* @param params
* @return
* @throws IOException
* @throws TemplateException
*/
public String processString(String templateName, Map<String, Object> params)
throws IOException, TemplateException {
Template template = configuration.getTemplate(templateName);
String htmlText = processTemplateIntoString(template, params);
return htmlText;
}
}

View File

@@ -1,12 +1,14 @@
package com.softdev.system.generator.util; package com.softdev.system.generator.util;
import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration; import freemarker.template.Configuration;
import freemarker.template.Template; import freemarker.template.Template;
import freemarker.template.TemplateException; import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler; import freemarker.template.TemplateExceptionHandler;
import lombok.extern.slf4j.Slf4j; 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.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.Locale; import java.util.Locale;
@@ -18,27 +20,37 @@ import java.util.Map;
* @author xuxueli 2018-05-02 19:56:00 * @author xuxueli 2018-05-02 19:56:00
*/ */
@Slf4j @Slf4j
@Component
public class FreemarkerUtil { public class FreemarkerUtil {
@Autowired
private Configuration configuration;
/**
* 传入需要转义的字符串进行转义
* 20200503 zhengkai.blog.csdn.net
* */
public static String escapeString(String originStr){
return originStr.replaceAll("","\\#").replaceAll("","\\$");
}
/** /**
* freemarker config * freemarker config
*/ */
private static Configuration freemarkerConfig = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); private static Configuration freemarkerConfig = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
static{ static{
String templatePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
int wei = templatePath.lastIndexOf("WEB-INF/classes/");
if (wei > -1) {
templatePath = templatePath.substring(0, wei);
}
try { try {
freemarkerConfig.setDirectoryForTemplateLoading(new File(templatePath, "templates/xxl-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.setNumberFormat("#");
freemarkerConfig.setClassicCompatible(true); freemarkerConfig.setClassicCompatible(true);
freemarkerConfig.setDefaultEncoding("UTF-8"); freemarkerConfig.setDefaultEncoding("UTF-8");
freemarkerConfig.setLocale(Locale.CHINA); freemarkerConfig.setLocale(Locale.CHINA);
freemarkerConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); freemarkerConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
} catch (IOException e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
} }
} }
@@ -73,7 +85,7 @@ public class FreemarkerUtil {
throws IOException, TemplateException { throws IOException, TemplateException {
Template template = freemarkerConfig.getTemplate(templateName); Template template = freemarkerConfig.getTemplate(templateName);
String htmlText = processTemplateIntoString(template, params); String htmlText = escapeString(processTemplateIntoString(template, params));
return htmlText; return htmlText;
} }

View File

@@ -1,423 +1,472 @@
package com.softdev.system.generator.util; package com.softdev.system.generator.util;
import cn.hutool.core.util.XmlUtil; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONObject; import com.softdev.system.generator.entity.ClassInfo;
import com.softdev.system.generator.entity.ClassInfo; import com.softdev.system.generator.entity.FieldInfo;
import com.softdev.system.generator.entity.FieldInfo; import com.softdev.system.generator.entity.ParamInfo;
import com.softdev.system.generator.entity.ParamInfo;
import org.w3c.dom.Document; import java.io.IOException;
import java.math.BigDecimal;
import java.io.IOException; import java.util.ArrayList;
import java.math.BigDecimal; import java.util.Arrays;
import java.util.ArrayList; import java.util.Date;
import java.util.Date; import java.util.List;
import java.util.List; import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
* @author zhengkai.blog.csdn.net * 表格解析Util
*/ * @author zhengkai.blog.csdn.net
public class TableParseUtil { */
public class TableParseUtil {
/**
* 解析建表SQL生成代码model-dao-xml /**
* * 解析DDL SQL生成类信息
* @param paramInfo * @param paramInfo
* @return * @return
*/ */
public static ClassInfo processTableIntoClassInfo(ParamInfo paramInfo) public static ClassInfo processTableIntoClassInfo(ParamInfo paramInfo)
throws IOException { throws IOException {
//process the param //process the param
String tableSql=paramInfo.getTableSql(); String tableSql=paramInfo.getTableSql();
String nameCaseType=paramInfo.getNameCaseType(); String nameCaseType=paramInfo.getNameCaseType();
String tinyintTransType=paramInfo.getTinyintTransType(); String tinyintTransType=paramInfo.getTinyintTransType();
if (tableSql==null || tableSql.trim().length()==0) { if (tableSql==null || tableSql.trim().length()==0) {
throw new CodeGenerateException("Table structure can not be empty."); throw new CodeGenerateException("Table structure can not be empty. 表结构不能为空。");
} }
//deal with special character //deal with special character
tableSql = tableSql.trim().replaceAll("'","`").replaceAll("\"","`").replaceAll("",",").toLowerCase(); tableSql = tableSql.trim().replaceAll("'","`").replaceAll("\"","`").replaceAll("",",").toLowerCase();
//deal with java string copy \n" //deal with java string copy \n"
tableSql = tableSql.trim().replaceAll("n`","").replaceAll("\\+","").replaceAll("``","`").replaceAll("\\\\",""); tableSql = tableSql.trim().replaceAll("\\\\n`","").replaceAll("\\+","").replaceAll("``","`").replaceAll("\\\\","");
// table Name // table Name
String tableName = null; String tableName = null;
if (tableSql.contains("TABLE") && tableSql.contains("(")) { if (tableSql.contains("TABLE") && tableSql.contains("(")) {
tableName = tableSql.substring(tableSql.indexOf("TABLE")+5, tableSql.indexOf("(")); tableName = tableSql.substring(tableSql.indexOf("TABLE")+5, tableSql.indexOf("("));
} else if (tableSql.contains("table") && tableSql.contains("(")) { } else if (tableSql.contains("table") && tableSql.contains("(")) {
tableName = tableSql.substring(tableSql.indexOf("table")+5, tableSql.indexOf("(")); tableName = tableSql.substring(tableSql.indexOf("table")+5, tableSql.indexOf("("));
} else { } else {
throw new CodeGenerateException("Table structure anomaly."); throw new CodeGenerateException("Table structure incorrect.表结构不正确。");
} }
//新增处理create table if not exists members情况 //新增处理create table if not exists members情况
if (tableName.contains("if not exists")) { if (tableName.contains("if not exists")) {
tableName=tableName.replaceAll("if not exists",""); tableName=tableName.replaceAll("if not exists","");
} }
if (tableName.contains("`")) { if (tableName.contains("`")) {
tableName = tableName.substring(tableName.indexOf("`")+1, tableName.lastIndexOf("`")); tableName = tableName.substring(tableName.indexOf("`")+1, tableName.lastIndexOf("`"));
}else{ }else{
//空格开头的,需要替换掉\n\t空格 //空格开头的,需要替换掉\n\t空格
tableName=tableName.replaceAll(" ","").replaceAll("\n","").replaceAll("\t",""); tableName=tableName.replaceAll(" ","").replaceAll("\n","").replaceAll("\t","");
} }
//优化对byeas`.`ct_bd_customerdiscount这种命名的支持 //优化对byeas`.`ct_bd_customerdiscount这种命名的支持
if(tableName.contains("`.`")){ if(tableName.contains("`.`")){
tableName=tableName.substring(tableName.indexOf("`.`")+3); tableName=tableName.substring(tableName.indexOf("`.`")+3);
}else if(tableName.contains(".")){ }else if(tableName.contains(".")){
//优化对likeu.members这种命名的支持 //优化对likeu.members这种命名的支持
tableName=tableName.substring(tableName.indexOf(".")+1); tableName=tableName.substring(tableName.indexOf(".")+1);
} }
// class Name // class Name
String className = StringUtils.upperCaseFirst(StringUtils.underlineToCamelCase(tableName)); String className = StringUtils.upperCaseFirst(StringUtils.underlineToCamelCase(tableName));
if (className.contains("_")) { if (className.contains("_")) {
className = className.replaceAll("_", ""); className = className.replaceAll("_", "");
} }
// class Comment // class Comment
String classComment = null; String classComment = null;
//mysql是comment=,pgsql/oracle是comment on table, //mysql是comment=,pgsql/oracle是comment on table,
if (tableSql.contains("comment=")) { //2020-05-25 优化表备注的获取逻辑
String classCommentTmp = tableSql.substring(tableSql.lastIndexOf("comment=")+8).replaceAll("`","").trim(); if (tableSql.contains("comment=")||tableSql.contains("comment on table")) {
if (classCommentTmp.indexOf(" ")!=classCommentTmp.lastIndexOf(" ")) { String classCommentTmp = (tableSql.contains("comment="))?
classCommentTmp = classCommentTmp.substring(classCommentTmp.indexOf(" ")+1, classCommentTmp.lastIndexOf(" ")); tableSql.substring(tableSql.lastIndexOf("comment=")+8).trim():tableSql.substring(tableSql.lastIndexOf("comment on table")+17).trim();
} if (classCommentTmp.contains("`")) {
if (classCommentTmp!=null && classCommentTmp.trim().length()>0) { classCommentTmp = classCommentTmp.substring(classCommentTmp.indexOf("`")+1);
classComment = classCommentTmp; classCommentTmp = classCommentTmp.substring(0,classCommentTmp.indexOf("`"));
}else{ classComment = classCommentTmp;
//修复表备注为空问题 }else{
classComment = className; //非常规的没法分析
} classComment = className;
}else if(tableSql.contains("comment on table")) { }
//COMMENT ON TABLE CT_BAS_FEETYPE IS 'CT_BAS_FEETYPE'; }else{
String classCommentTmp = tableSql.substring(tableSql.lastIndexOf("comment on table")+17).trim(); //修复表备注为空问题
//证明这是一个常规的COMMENT ON TABLE xxx IS 'xxxx' classComment = tableName;
if (classCommentTmp.contains("`")) { }
classCommentTmp = classCommentTmp.substring(classCommentTmp.indexOf("`")+1); //如果备注跟;混在一起,需要替换掉
classCommentTmp = classCommentTmp.substring(0,classCommentTmp.indexOf("`")); classComment=classComment.replaceAll(";","");
classComment = classCommentTmp; // field List
}else{ List<FieldInfo> fieldList = new ArrayList<FieldInfo>();
//非常规的没法分析
classComment = tableName; // 正常( ) 内的一定是字段相关的定义。
} String fieldListTmp = tableSql.substring(tableSql.indexOf("(")+1, tableSql.lastIndexOf(")"));
}else{
//修复表备注为空问题 // 匹配 comment替换备注里的小逗号, 防止不小心被当成切割符号切割
classComment = tableName; String commentPattenStr1="comment `(.*?)\\`";
} Matcher matcher1 = Pattern.compile(commentPattenStr1).matcher(fieldListTmp);
//如果备注跟;混在一起,需要替换掉 while(matcher1.find()){
classComment=classComment.replaceAll(";","");
// field List String commentTmp = matcher1.group();
List<FieldInfo> fieldList = new ArrayList<FieldInfo>(); //2018-9-27 zhengk 不替换只处理支持COMMENT评论里面多种注释
//commentTmp = commentTmp.replaceAll("\\ comment `|\\`", " "); // "\\{|\\}"
// 正常( ) 内的一定是字段相关的定义。
String fieldListTmp = tableSql.substring(tableSql.indexOf("(")+1, tableSql.lastIndexOf(")")); if (commentTmp.contains(",")) {
String commentTmpFinal = commentTmp.replaceAll(",", "");
// 匹配 comment替换备注里的小逗号, 防止不小心被当成切割符号切割 fieldListTmp = fieldListTmp.replace(matcher1.group(), commentTmpFinal);
String commentPattenStr1="comment `(.*?)\\`"; }
Matcher matcher1 = Pattern.compile(commentPattenStr1).matcher(fieldListTmp); }
while(matcher1.find()){ //2018-10-18 zhengkai 新增支持double(10, 2)等类型中有英文逗号的特殊情况
String commentPattenStr2="\\`(.*?)\\`";
String commentTmp = matcher1.group(); Matcher matcher2 = Pattern.compile(commentPattenStr2).matcher(fieldListTmp);
//2018-9-27 zhengk 不替换只处理支持COMMENT评论里面多种注释 while(matcher2.find()){
//commentTmp = commentTmp.replaceAll("\\ comment `|\\`", " "); // "\\{|\\}" String commentTmp2 = matcher2.group();
if (commentTmp2.contains(",")) {
if (commentTmp.contains(",")) { String commentTmpFinal = commentTmp2.replaceAll(",", "").replaceAll("\\(", "").replaceAll("\\)", "");
String commentTmpFinal = commentTmp.replaceAll(",", ""); fieldListTmp = fieldListTmp.replace(matcher2.group(), commentTmpFinal);
fieldListTmp = fieldListTmp.replace(matcher1.group(), commentTmpFinal); }
} }
} //2018-10-18 zhengkai 新增支持double(10, 2)等类型中有英文逗号的特殊情况
//2018-10-18 zhengkai 新增支持double(10, 2)等类型中有英文逗号的特殊情况 String commentPattenStr3="\\((.*?)\\)";
String commentPattenStr2="\\`(.*?)\\`"; Matcher matcher3 = Pattern.compile(commentPattenStr3).matcher(fieldListTmp);
Matcher matcher2 = Pattern.compile(commentPattenStr2).matcher(fieldListTmp); while(matcher3.find()){
while(matcher2.find()){ String commentTmp3 = matcher3.group();
String commentTmp2 = matcher2.group(); if (commentTmp3.contains(",")) {
if (commentTmp2.contains(",")) { String commentTmpFinal = commentTmp3.replaceAll(",", "");
String commentTmpFinal = commentTmp2.replaceAll(",", "").replaceAll("\\(", "").replaceAll("\\)", ""); fieldListTmp = fieldListTmp.replace(matcher3.group(), commentTmpFinal);
fieldListTmp = fieldListTmp.replace(matcher2.group(), commentTmpFinal); }
} }
} String[] fieldLineList = fieldListTmp.split(",");
//2018-10-18 zhengkai 新增支持double(10, 2)等类型中有英文逗号的特殊情况 if (fieldLineList.length > 0) {
String commentPattenStr3="\\((.*?)\\)"; int i=0;
Matcher matcher3 = Pattern.compile(commentPattenStr3).matcher(fieldListTmp); //i为了解决primary key关键字出现的地方出现在前3行一般和id有关
while(matcher3.find()){ for (String columnLine :fieldLineList) {
String commentTmp3 = matcher3.group(); i++;
if (commentTmp3.contains(",")) { columnLine = columnLine.replaceAll("\n","").replaceAll("\t","").trim();
String commentTmpFinal = commentTmp3.replaceAll(",", ""); // `userid` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
fieldListTmp = fieldListTmp.replace(matcher3.group(), commentTmpFinal); // 2018-9-18 zhengk 修改为contains提升匹配率和匹配不按照规矩出牌的语句
} // 2018-11-8 zhengkai 修复tornadoorz反馈的KEY FK_permission_id (permission_id),KEY FK_role_id (role_id)情况
} // 2019-2-22 zhengkai 要在条件中使用复杂的表达式
String[] fieldLineList = fieldListTmp.split(","); // 2019-4-29 zhengkai 优化对普通和特殊storage关键字的判断感谢@AhHeadFloating的反馈
if (fieldLineList.length > 0) { boolean specialFlag=(!columnLine.contains("key ")&&!columnLine.contains("constraint")&&!columnLine.contains("using")&&!columnLine.contains("unique")
int i=0; &&!(columnLine.contains("primary ")&&columnLine.indexOf("storage")+3>columnLine.indexOf("("))
//i为了解决primary key关键字出现的地方出现在前3行一般和id有关 &&!columnLine.contains("pctincrease")
for (String columnLine :fieldLineList) { &&!columnLine.contains("buffer_pool")&&!columnLine.contains("tablespace")
i++; &&!(columnLine.contains("primary ")&&i>3));
columnLine = columnLine.replaceAll("\n","").replaceAll("\t","").trim(); if (specialFlag){
// `userid` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID', //如果是oracle的number(x,x),可能出现最后分割残留的,x),这里做排除处理
// 2018-9-18 zhengk 修改为contains提升匹配率和匹配不按照规矩出牌的语句 if(columnLine.length()<5) {continue;}
// 2018-11-8 zhengkai 修复tornadoorz反馈的KEY FK_permission_id (permission_id),KEY FK_role_id (role_id)情况 //2018-9-16 zhengkai 支持'符号以及空格的oracle语句// userid` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
// 2019-2-22 zhengkai 要在条件中使用复杂的表达式 String columnName = "";
// 2019-4-29 zhengkai 优化对普通和特殊storage关键字的判断感谢@AhHeadFloating的反馈 columnLine=columnLine.replaceAll("`"," ").replaceAll("\""," ").replaceAll("'","").replaceAll(" "," ").trim();
boolean specialFlag=(!columnLine.contains("key ")&&!columnLine.contains("constraint")&&!columnLine.contains("using")&&!columnLine.contains("unique") //如果遇到username varchar(65) default '' not null,这种情况,判断第一个空格是否比第一个引号前
&&!(columnLine.contains("primary ")&&columnLine.indexOf("storage")+3>columnLine.indexOf("(")) columnName = columnLine.substring(0, columnLine.indexOf(" "));
&&!columnLine.contains("pctincrease") // field Name
&&!columnLine.contains("buffer_pool")&&!columnLine.contains("tablespace") // 2019-09-08 yj 添加是否下划线转换为驼峰的判断
&&!(columnLine.contains("primary ")&&i>3)); String fieldName=null;
if (specialFlag){ if(ParamInfo.NAME_CASE_TYPE.CAMEL_CASE.equals(nameCaseType)){
//如果是oracle的number(x,x),可能出现最后分割残留的,x),这里做排除处理 fieldName = StringUtils.lowerCaseFirst(StringUtils.underlineToCamelCase(columnName));
if(columnLine.length()<5) {continue;} if (fieldName.contains("_")) {
//2018-9-16 zhengkai 支持'符号以及空格的oracle语句// userid` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID', fieldName = fieldName.replaceAll("_", "");
String columnName = ""; }
columnLine=columnLine.replaceAll("`"," ").replaceAll("\""," ").replaceAll("'","").replaceAll(" "," ").trim(); }else if(ParamInfo.NAME_CASE_TYPE.UNDER_SCORE_CASE.equals(nameCaseType)){
//如果遇到username varchar(65) default '' not null,这种情况,判断第一个空格是否比第一个引号前 fieldName = StringUtils.lowerCaseFirst(columnName);
columnName = columnLine.substring(0, columnLine.indexOf(" ")); }else if(ParamInfo.NAME_CASE_TYPE.UPPER_UNDER_SCORE_CASE.equals(nameCaseType)){
// field Name fieldName = StringUtils.lowerCaseFirst(columnName.toUpperCase());
// 2019-09-08 yj 添加是否下划线转换为驼峰的判断 }else{
String fieldName=null; fieldName=columnName;
if(ParamInfo.NAME_CASE_TYPE.CAMEL_CASE.equals(nameCaseType)){ }
fieldName = StringUtils.lowerCaseFirst(StringUtils.underlineToCamelCase(columnName));
if (fieldName.contains("_")) { // field class
fieldName = fieldName.replaceAll("_", ""); columnLine = columnLine.substring(columnLine.indexOf("`")+1).trim();
} // int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
}else if(ParamInfo.NAME_CASE_TYPE.UNDER_SCORE_CASE.equals(nameCaseType)){ String fieldClass = Object.class.getSimpleName();
fieldName = StringUtils.lowerCaseFirst(columnName); //2018-9-16 zhengk 补充char/clob/blob/json等类型如果类型未知默认为String
}else if(ParamInfo.NAME_CASE_TYPE.UPPER_UNDER_SCORE_CASE.equals(nameCaseType)){ //2018-11-22 lshz0088 处理字段类型的时候不严谨columnLine.contains(" int") 类似这种的,可在前后适当加一些空格之类的加以区分,否则当我的字段包含这些字符的时候,产生类型判断问题。
fieldName = StringUtils.lowerCaseFirst(columnName.toUpperCase()); //2020-05-03 MOSHOW.K.ZHENG 优化对所有类型的处理
}else{ if (columnLine.contains(" tinyint") ) {
fieldName=columnName; //20191115 MOSHOW.K.ZHENG 支持对tinyint的特殊处理
} fieldClass=tinyintTransType;
}
// field class else if (columnLine.contains(" int") || columnLine.contains(" smallint")) {
columnLine = columnLine.substring(columnLine.indexOf("`")+1).trim(); fieldClass = Integer.class.getSimpleName();
// int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID', } else if (columnLine.contains(" bigint")) {
String fieldClass = Object.class.getSimpleName(); fieldClass = Long.class.getSimpleName();
//2018-9-16 zhengk 补充char/clob/blob/json等类型如果类型未知默认为String } else if (columnLine.contains(" float")) {
//2018-11-22 lshz0088 处理字段类型的时候不严谨columnLine.contains(" int") 类似这种的,可在前后适当加一些空格之类的加以区分,否则当我的字段包含这些字符的时候,产生类型判断问题。 fieldClass = Float.class.getSimpleName();
if (columnLine.contains(" int") || columnLine.contains("smallint")) { } else if (columnLine.contains(" double")) {
fieldClass = Integer.class.getSimpleName(); fieldClass = Double.class.getSimpleName();
} else if (columnLine.contains("bigint")) { } else if (columnLine.contains(" time") || columnLine.contains(" date") || columnLine.contains(" datetime") || columnLine.contains(" timestamp")) {
fieldClass = Long.class.getSimpleName(); fieldClass = Date.class.getSimpleName();
} else if (columnLine.contains("float")) { } else if (columnLine.contains(" varchar") || columnLine.contains(" text")|| columnLine.contains(" char")
fieldClass = Float.class.getSimpleName(); || columnLine.contains(" clob")||columnLine.contains(" blob")||columnLine.contains(" json")) {
} else if (columnLine.contains("double")) { fieldClass = String.class.getSimpleName();
fieldClass = Double.class.getSimpleName(); } else if (columnLine.contains(" decimal")||columnLine.contains(" number")) {
} else if (columnLine.contains("time") || columnLine.contains("date") || columnLine.contains("datetime") || columnLine.contains("timestamp")) { //2018-11-22 lshz0088 建议对number类型增加intlongBigDecimal的区分判断
fieldClass = Date.class.getSimpleName(); //如果startKh大于等于0则表示有设置取值范围
} else if (columnLine.contains("varchar") || columnLine.contains(" text")|| columnLine.contains("char") int startKh=columnLine.indexOf("(");
|| columnLine.contains("clob")||columnLine.contains("blob")||columnLine.contains("json")) { if(startKh>=0){
fieldClass = String.class.getSimpleName(); int endKh=columnLine.indexOf(")",startKh);
} else if (columnLine.contains("decimal")||columnLine.contains(" number")) { String[] fanwei=columnLine.substring(startKh+1,endKh).split("");
//2018-11-22 lshz0088 建议对number类型增加intlongBigDecimal的区分判断 //2019-1-5 zhengk 修复@arthaschan反馈的超出范围错误
//如果startKh大于等于0则表示有设置取值范围 //System.out.println("fanwei"+ JSON.toJSONString(fanwei));
int startKh=columnLine.indexOf("("); // //number(20,6) fanwei["20","6"]
if(startKh>=0){ // //number(0,6) fanwei["0","6"]
int endKh=columnLine.indexOf(")",startKh); // //number(20,0) fanwei["20","0"]
String[] fanwei=columnLine.substring(startKh+1,endKh).split(""); // //number(20) fanwei["20"]
//2019-1-5 zhengk 修复@arthaschan反馈的超出范围错误 //如果括号里是1位或者2位且第二位为0则进行特殊处理。只有有小数位都设置为BigDecimal。
//System.out.println("fanwei"+ JSON.toJSONString(fanwei)); if((fanwei.length>1&&"0".equals(fanwei[1]))||fanwei.length==1){
// //number(20,6) fanwei["20","6"] int length=Integer.parseInt(fanwei[0]);
// //number(0,6) fanwei["0","6"] if(fanwei.length>1) {
// //number(20,0) fanwei["20","0"] length=Integer.valueOf(fanwei[1]);
// //number(20) fanwei["20"] }
//如果括号里是1位或者2位且第二位为0则进行特殊处理。只有有小数位都设置为BigDecimal。 //数字范围9位及一下用Integer大的用Long
if((fanwei.length>1&&"0".equals(fanwei[1]))||fanwei.length==1){ if(length<=9){
int length=Integer.parseInt(fanwei[0]); fieldClass = Integer.class.getSimpleName();
if(fanwei.length>1) { }else{
length=Integer.valueOf(fanwei[1]); fieldClass = Long.class.getSimpleName();
} }
//数字范围9位及一下用Integer大的用Long }else{
if(length<=9){ //有小数位数一律使用BigDecimal
fieldClass = Integer.class.getSimpleName(); fieldClass = BigDecimal.class.getSimpleName();
}else{ }
fieldClass = Long.class.getSimpleName(); }else{
} fieldClass = BigDecimal.class.getSimpleName();
}else{ }
//有小数位数一律使用BigDecimal } else if (columnLine.contains(" boolean")) {
fieldClass = BigDecimal.class.getSimpleName(); //20190910 MOSHOW.K.ZHENG 新增对boolean的处理感谢@violinxsc的反馈以及修复tinyint类型字段无法生成boolean类型问题感谢@hahaYhui的反馈
} fieldClass = Boolean.class.getSimpleName();
}else{ } else {
fieldClass = BigDecimal.class.getSimpleName(); fieldClass = String.class.getSimpleName();
} }
} else if (columnLine.contains("boolean")) {
//20190910 MOSHOW.K.ZHENG 新增对boolean的处理感谢@violinxsc的反馈以及修复tinyint类型字段无法生成boolean类型问题感谢@hahaYhui的反馈 // field commentMySQL的一般位于field行而pgsql和oralce多位于后面。
fieldClass = Boolean.class.getSimpleName(); String fieldComment = null;
} else if (columnLine.contains("tinyint") ) { if(tableSql.contains("comment on column")&&(tableSql.contains("."+columnName+" is ")||tableSql.contains(".`"+columnName+"` is"))){
//20191115 MOSHOW.K.ZHENG 支持对tinyint的特殊处理 //新增对pgsql/oracle的字段备注支持
fieldClass=tinyintTransType; //COMMENT ON COLUMN public.check_info.check_name IS '检查者名称';
} else { //2018-11-22 lshz0088 正则表达式的点号前面应该加上两个反斜杠,否则会认为是任意字符
fieldClass = String.class.getSimpleName(); //2019-4-29 zhengkai 优化对oracle注释comment on column的支持@liukex
} tableSql=tableSql.replaceAll(".`"+columnName+"` is","."+columnName+" is");
Matcher columnCommentMatcher = Pattern.compile("\\."+columnName+" is `").matcher(tableSql);
// field commentMySQL的一般位于field行而pgsql和oralce多位于后面。 fieldComment=columnName;
String fieldComment = null; while(columnCommentMatcher.find()){
if(tableSql.contains("comment on column")&&(tableSql.contains("."+columnName+" is ")||tableSql.contains(".`"+columnName+"` is"))){ String columnCommentTmp = columnCommentMatcher.group();
//新增对pgsql/oracle的字段备注支持 //System.out.println(columnCommentTmp);
//COMMENT ON COLUMN public.check_info.check_name IS '检查者名称'; fieldComment = tableSql.substring(tableSql.indexOf(columnCommentTmp)+columnCommentTmp.length()).trim();
//2018-11-22 lshz0088 正则表达式的点号前面应该加上两个反斜杠,否则会认为是任意字符 fieldComment = fieldComment.substring(0,fieldComment.indexOf("`")).trim();
//2019-4-29 zhengkai 优化对oracle注释comment on column的支持@liukex }
tableSql=tableSql.replaceAll(".`"+columnName+"` is","."+columnName+" is"); }else if (columnLine.contains(" comment")) {
Matcher columnCommentMatcher = Pattern.compile("\\."+columnName+" is `").matcher(tableSql); //20200518 zhengkai 修复包含comment关键字的问题
fieldComment=columnName; String commentTmp = columnLine.substring(columnLine.lastIndexOf("comment")+7).trim();
while(columnCommentMatcher.find()){ // '用户ID',
String columnCommentTmp = columnCommentMatcher.group(); if (commentTmp.contains("`") || commentTmp.indexOf("`")!=commentTmp.lastIndexOf("`")) {
System.out.println(columnCommentTmp); commentTmp = commentTmp.substring(commentTmp.indexOf("`")+1, commentTmp.lastIndexOf("`"));
fieldComment = tableSql.substring(tableSql.indexOf(columnCommentTmp)+columnCommentTmp.length()).trim(); }
fieldComment = fieldComment.substring(0,fieldComment.indexOf("`")).trim(); //解决最后一句是评论,无主键且连着)的问题:album_id int(3) default '1' null comment '相册id0 代表头像 1代表照片墙')
} if(commentTmp.contains(")")){
}else if (columnLine.contains("comment")) { commentTmp = commentTmp.substring(0, commentTmp.lastIndexOf(")")+1);
String commentTmp = columnLine.substring(columnLine.indexOf("comment")+7).trim(); }
// '用户ID', fieldComment = commentTmp;
if (commentTmp.contains("`") || commentTmp.indexOf("`")!=commentTmp.lastIndexOf("`")) { }else{
commentTmp = commentTmp.substring(commentTmp.indexOf("`")+1, commentTmp.lastIndexOf("`")); //修复comment不存在导致报错的问题
} fieldComment = columnName;
//解决最后一句是评论,无主键且连着)的问题:album_id int(3) default '1' null comment '相册id0 代表头像 1代表照片墙') }
if(commentTmp.contains(")")){
commentTmp = commentTmp.substring(0, commentTmp.lastIndexOf(")")+1); FieldInfo fieldInfo = new FieldInfo();
} fieldInfo.setColumnName(columnName);
fieldComment = commentTmp; fieldInfo.setFieldName(fieldName);
}else{ fieldInfo.setFieldClass(fieldClass);
//修复comment不存在导致报错的问题 fieldInfo.setFieldComment(fieldComment);
fieldComment = columnName;
} fieldList.add(fieldInfo);
}
FieldInfo fieldInfo = new FieldInfo(); }
fieldInfo.setColumnName(columnName); }
fieldInfo.setFieldName(fieldName);
fieldInfo.setFieldClass(fieldClass); if (fieldList.size() < 1) {
fieldInfo.setFieldComment(fieldComment); throw new CodeGenerateException("表结构分析失败请检查语句或者提交issue给我");
}
fieldList.add(fieldInfo);
} ClassInfo codeJavaInfo = new ClassInfo();
} codeJavaInfo.setTableName(tableName);
} codeJavaInfo.setClassName(className);
codeJavaInfo.setClassComment(classComment);
if (fieldList.size() < 1) { codeJavaInfo.setFieldList(fieldList);
throw new CodeGenerateException("表结构分析失败请检查语句或者提交issue给我");
} return codeJavaInfo;
}
ClassInfo codeJavaInfo = new ClassInfo(); /**
codeJavaInfo.setTableName(tableName); * 解析JSON生成类信息
codeJavaInfo.setClassName(className); * @param paramInfo
codeJavaInfo.setClassComment(classComment); * @return
codeJavaInfo.setFieldList(fieldList); */
public static ClassInfo processJsonToClassInfo(ParamInfo paramInfo){
return codeJavaInfo; ClassInfo codeJavaInfo = new ClassInfo();
} codeJavaInfo.setTableName("JsonDto");
/** codeJavaInfo.setClassName("JsonDto");
* parse JSON codeJavaInfo.setClassComment("JsonDto");
* @param paramInfo
* @return //support children json if forget to add '{' in front of json
*/ if(paramInfo.getTableSql().trim().startsWith("\"")){
public static ClassInfo processJsonToClassInfo(ParamInfo paramInfo){ paramInfo.setTableSql("{"+paramInfo.getTableSql());
ClassInfo codeJavaInfo = new ClassInfo(); }
codeJavaInfo.setTableName("JsonDto"); if(JSON.isValid(paramInfo.getTableSql())){
codeJavaInfo.setClassName("JsonDto"); if(paramInfo.getTableSql().trim().startsWith("{")){
codeJavaInfo.setClassComment("JsonDto"); JSONObject jsonObject = JSONObject.parseObject(paramInfo.getTableSql().trim());
//parse FieldList by JSONObject
//support children json if forget to add '{' in front of json codeJavaInfo.setFieldList(processJsonObjectToFieldList(jsonObject));
if(paramInfo.getTableSql().trim().startsWith("\"")){ }else if(paramInfo.getTableSql().trim().startsWith("[")){
paramInfo.setTableSql("{"+paramInfo.getTableSql()); JSONArray jsonArray=JSONArray.parseArray(paramInfo.getTableSql().trim());
} //parse FieldList by JSONObject
if(JSON.isValid(paramInfo.getTableSql())){ codeJavaInfo.setFieldList(processJsonObjectToFieldList(jsonArray.getJSONObject(0)));
if(paramInfo.getTableSql().trim().startsWith("{")){ }
JSONObject jsonObject = JSONObject.parseObject(paramInfo.getTableSql().trim()); }
//parse FieldList by JSONObject
codeJavaInfo.setFieldList(processJsonObjectToFieldList(jsonObject)); return codeJavaInfo;
}else if(paramInfo.getTableSql().trim().startsWith("[")){ }
JSONArray jsonArray=JSONArray.parseArray(paramInfo.getTableSql().trim()); /**
//parse FieldList by JSONObject * parse SQL by regex
codeJavaInfo.setFieldList(processJsonObjectToFieldList(jsonArray.getJSONObject(0))); * @author https://github.com/ydq
} * @param paramInfo
} * @return
*/
return codeJavaInfo; public static ClassInfo processTableToClassInfoByRegex(ParamInfo paramInfo){
} // field List
/** List<FieldInfo> fieldList = new ArrayList<FieldInfo>();
* parse SQL by regex //return classInfo
* @author https://github.com/ydq ClassInfo codeJavaInfo = new ClassInfo();
* @param paramInfo
* @return //匹配整个ddl将ddl分为表名列sql部分表注释
*/ String DDL_PATTEN_STR="\\s*create\\s+table\\s+(?<tableName>\\S+)[^\\(]*\\((?<columnsSQL>[\\s\\S]+)\\)[^\\)]+?(comment\\s*(=|on\\s+table)\\s*'(?<tableComment>.*?)'\\s*;?)?$";
public static ClassInfo processTableToClassInfoByRegex(ParamInfo paramInfo){
// field List Pattern DDL_PATTERN = Pattern.compile(DDL_PATTEN_STR, Pattern.CASE_INSENSITIVE);
List<FieldInfo> fieldList = new ArrayList<FieldInfo>();
//return classInfo //匹配列sql部分分别解析每一列的列名 类型 和列注释
ClassInfo codeJavaInfo = new ClassInfo(); String COL_PATTERN_STR="\\s*(?<fieldName>\\S+)\\s+(?<fieldType>\\w+)\\s*(?:\\([\\s\\d,]+\\))?((?!comment).)*(comment\\s*'(?<fieldComment>.*?)')?\\s*(,|$)";
//匹配整个ddl将ddl分为表名列sql部分表注释 Pattern COL_PATTERN = Pattern.compile(COL_PATTERN_STR, Pattern.CASE_INSENSITIVE);
String DDL_PATTEN_STR="\\s*create\\s+table\\s+(?<tableName>\\S+)[^\\(]*\\((?<columnsSQL>[\\s\\S]+)\\)[^\\)]+?(comment\\s*(=|on\\s+table)\\s*'(?<tableComment>.*?)'\\s*;?)?$";
Matcher matcher = DDL_PATTERN.matcher(paramInfo.getTableSql().trim());
Pattern DDL_PATTERN = Pattern.compile(DDL_PATTEN_STR, Pattern.CASE_INSENSITIVE); if (matcher.find()){
String tableName = matcher.group("tableName");
//匹配列sql部分分别解析每一列的列名 类型 和列注释 String tableComment = matcher.group("tableComment");
String COL_PATTERN_STR="\\s*(?<fieldName>\\S+)\\s+(?<fieldType>\\w+)\\s*(?:\\([\\s\\d,]+\\))?((?!comment).)*(comment\\s*'(?<fieldComment>.*?)')?\\s*(,|$)"; codeJavaInfo.setTableName(tableName.replaceAll("'",""));
codeJavaInfo.setClassName(tableName.replaceAll("'",""));
Pattern COL_PATTERN = Pattern.compile(COL_PATTERN_STR, Pattern.CASE_INSENSITIVE); codeJavaInfo.setClassComment(tableComment.replaceAll("'",""));
String columnsSQL = matcher.group("columnsSQL");
Matcher matcher = DDL_PATTERN.matcher(paramInfo.getTableSql().trim()); if (columnsSQL != null && columnsSQL.length() > 0){
if (matcher.find()){ Matcher colMatcher = COL_PATTERN.matcher(columnsSQL);
String tableName = matcher.group("tableName"); while (colMatcher.find()){
String tableComment = matcher.group("tableComment"); String fieldName = colMatcher.group("fieldName");
codeJavaInfo.setTableName(tableName.replaceAll("'","")); String fieldType = colMatcher.group("fieldType");
codeJavaInfo.setClassName(tableName.replaceAll("'","")); String fieldComment = colMatcher.group("fieldComment");
codeJavaInfo.setClassComment(tableComment.replaceAll("'","")); if (!"key".equalsIgnoreCase(fieldType)){
String columnsSQL = matcher.group("columnsSQL"); FieldInfo fieldInfo = new FieldInfo();
if (columnsSQL != null && columnsSQL.length() > 0){ fieldInfo.setFieldName(fieldName.replaceAll("'",""));
Matcher colMatcher = COL_PATTERN.matcher(columnsSQL); fieldInfo.setColumnName(fieldName.replaceAll("'",""));
while (colMatcher.find()){ fieldInfo.setFieldClass(fieldType.replaceAll("'",""));
String fieldName = colMatcher.group("fieldName"); fieldInfo.setFieldComment(fieldComment.replaceAll("'",""));
String fieldType = colMatcher.group("fieldType"); fieldList.add(fieldInfo);
String fieldComment = colMatcher.group("fieldComment"); }
if (!"key".equalsIgnoreCase(fieldType)){ }
FieldInfo fieldInfo = new FieldInfo(); }
fieldInfo.setFieldName(fieldName.replaceAll("'","")); codeJavaInfo.setFieldList(fieldList);
fieldInfo.setColumnName(fieldName.replaceAll("'","")); }
fieldInfo.setFieldClass(fieldType.replaceAll("'","")); return codeJavaInfo;
fieldInfo.setFieldComment(fieldComment.replaceAll("'","")); }
fieldList.add(fieldInfo); public static List<FieldInfo> processJsonObjectToFieldList(JSONObject jsonObject){
} // field List
} List<FieldInfo> fieldList = new ArrayList<FieldInfo>();
} jsonObject.keySet().stream().forEach(jsonField->{
codeJavaInfo.setFieldList(fieldList); FieldInfo fieldInfo = new FieldInfo();
} fieldInfo.setFieldName(jsonField);
return codeJavaInfo; fieldInfo.setColumnName(jsonField);
} fieldInfo.setFieldClass(String.class.getSimpleName());
public static List<FieldInfo> processJsonObjectToFieldList(JSONObject jsonObject){ fieldInfo.setFieldComment("father:"+jsonField);
// field List fieldList.add(fieldInfo);
List<FieldInfo> fieldList = new ArrayList<FieldInfo>(); if(jsonObject.get(jsonField) instanceof JSONArray){
jsonObject.keySet().stream().forEach(jsonField->{ jsonObject.getJSONArray(jsonField).stream().forEach(arrayObject->{
FieldInfo fieldInfo = new FieldInfo(); FieldInfo fieldInfo2 = new FieldInfo();
fieldInfo.setFieldName(jsonField); fieldInfo2.setFieldName(arrayObject.toString());
fieldInfo.setColumnName(jsonField); fieldInfo2.setColumnName(arrayObject.toString());
fieldInfo.setFieldClass(String.class.getSimpleName()); fieldInfo2.setFieldClass(String.class.getSimpleName());
fieldInfo.setFieldComment("father:"+jsonField); fieldInfo2.setFieldComment("children:"+arrayObject.toString());
fieldList.add(fieldInfo); fieldList.add(fieldInfo2);
if(jsonObject.get(jsonField) instanceof JSONArray){ });
jsonObject.getJSONArray(jsonField).stream().forEach(arrayObject->{ }else if(jsonObject.get(jsonField) instanceof JSONObject){
FieldInfo fieldInfo2 = new FieldInfo(); jsonObject.getJSONObject(jsonField).keySet().stream().forEach(arrayObject->{
fieldInfo2.setFieldName(arrayObject.toString()); FieldInfo fieldInfo2 = new FieldInfo();
fieldInfo2.setColumnName(arrayObject.toString()); fieldInfo2.setFieldName(arrayObject.toString());
fieldInfo2.setFieldClass(String.class.getSimpleName()); fieldInfo2.setColumnName(arrayObject.toString());
fieldInfo2.setFieldComment("children:"+arrayObject.toString()); fieldInfo2.setFieldClass(String.class.getSimpleName());
fieldList.add(fieldInfo2); 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()); if(fieldList.size()<1){
fieldInfo2.setColumnName(arrayObject.toString()); throw new CodeGenerateException("JSON解析失败");
fieldInfo2.setFieldClass(String.class.getSimpleName()); }
fieldInfo2.setFieldComment("children:"+arrayObject.toString()); return fieldList;
fieldList.add(fieldInfo2); }
});
} public static ClassInfo processInsertSqlToClassInfo(ParamInfo paramInfo) {
}); // field List
if(fieldList.size()<1){ List<FieldInfo> fieldList = new ArrayList<FieldInfo>();
throw new CodeGenerateException("JSON解析失败"); //return classInfo
} ClassInfo codeJavaInfo = new ClassInfo();
return fieldList;
} //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-request-attributes: true
expose-session-attributes: true expose-session-attributes: true
expose-spring-macro-helpers: true expose-spring-macro-helpers: true
#template-loader-path: classpath:/templates/ settings:
number_format: 0.##
default_encoding: UTF-8
#template_loader: /templates/
mvc: mvc:
static-path-pattern: /static/** static-path-pattern: /static/**

View File

@@ -0,0 +1 @@
{"version": "20200522"}

View File

@@ -0,0 +1,182 @@
[
{
"id": "10",
"name": "swagger-ui",
"group": "ui",
"description": "swagger-ui"
},
{
"id": "11",
"name": "element-ui",
"group": "ui",
"description": "element-ui"
},
{
"id": "12",
"name": "bootstrap-ui",
"group": "ui",
"description": "bootstrap-ui"
},
{
"id": "13",
"name": "layui-edit",
"group": "ui",
"description": "layui-edit"
},
{
"id": "14",
"name": "layui-list",
"group": "ui",
"description": "layui-list"
},
{
"id": "20",
"name": "controller",
"group": "mybatis",
"description": "controller"
},
{
"id": "21",
"name": "service",
"group": "mybatis",
"description": "service"
},
{
"id": "22",
"name": "service_impl",
"group": "mybatis",
"description": "service_impl"
},
{
"id": "23",
"name": "mapper",
"group": "mybatis",
"description": "mapper"
},
{
"id": "24",
"name": "mybatis",
"group": "mybatis",
"description": "mybatis"
},
{
"id": "25",
"name": "model",
"group": "mybatis",
"description": "model"
},
{
"id": "26",
"name": "mapper2",
"group": "mybatis",
"description": "mapper annotation"
},
{
"id": "30",
"name": "entity",
"group": "jpa",
"description": "entity"
},
{
"id": "31",
"name": "repository",
"group": "jpa",
"description": "repository"
},
{
"id": "32",
"name": "jpacontroller",
"group": "jpa",
"description": "jpacontroller"
},
{
"id": "40",
"name": "jtdao",
"group": "jdbc-template",
"description": "jtdao"
},
{
"id": "41",
"name": "jtdaoimpl",
"group": "jdbc-template",
"description": "jtdaoimpl"
},
{
"id": "50",
"name": "beetlmd",
"group": "beetlsql",
"description": "beetlmd"
},
{
"id": "51",
"name": "beetlentity",
"group": "beetlsql",
"description": "beetlentity"
},
{
"id": "52",
"name": "beetlcontroller",
"group": "beetlsql",
"description": "beetlcontroller"
},
{
"id": "60",
"name": "pluscontroller",
"group": "mybatis-plus",
"description": "pluscontroller"
},
{
"id": "61",
"name": "plusmapper",
"group": "mybatis-plus",
"description": "plusmapper"
},
{
"id": "62",
"name": "plusentity",
"group": "mybatis-plus",
"description": "plusentity"
},
{
"id": "70",
"name": "util",
"group": "util",
"description": "util"
},
{
"id": "71",
"name": "json",
"group": "util",
"description": "json"
},
{
"id": "72",
"name": "xml",
"group": "util",
"description": "xml"
},
{
"id": "80",
"name": "select",
"group": "sql",
"description": "select"
},
{
"id": "81",
"name": "insert",
"group": "sql",
"description": "insert"
},
{
"id": "82",
"name": "update",
"group": "sql",
"description": "update"
},
{
"id": "83",
"name": "delete",
"group": "sql",
"description": "delete"
}
]

View File

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

View File

@@ -4,18 +4,22 @@ import java.util.Date;
import java.util.List; import java.util.List;
/** /**
* ${classInfo.classComment} * @description ${classInfo.classComment}
* @author ${authorName} ${.now?string('yyyy-MM-dd')} * @author ${authorName}
*/ * @date ${.now?string('yyyy-MM-dd')}
@Data */
@Data<#if swagger?exists && swagger==true>
@ApiModel("${classInfo.classComment}")</#if>
public class ${classInfo.className} implements Serializable { public class ${classInfo.className} implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
<#if classInfo.fieldList?exists && classInfo.fieldList?size gt 0> <#if classInfo.fieldList?exists && classInfo.fieldList?size gt 0>
<#list classInfo.fieldList as fieldItem > <#list classInfo.fieldList as fieldItem >
/** /**
* ${fieldItem.fieldComment} * ${fieldItem.fieldComment}
*/ */<#if swagger?exists && swagger==true>
@ApiModelProperty("${fieldItem.fieldComment}")</#if>
private ${fieldItem.fieldClass} ${fieldItem.fieldName}; private ${fieldItem.fieldClass} ${fieldItem.fieldName};
</#list> </#list>
@@ -23,4 +27,4 @@ public class ${classInfo.className} implements Serializable {
} }
</#if> </#if>
} }

View File

@@ -1,26 +0,0 @@
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
* ${classInfo.classComment}
* @author ${authorName} ${.now?string('yyyy-MM-dd')}
*/
@Data
@ApiModel("${classInfo.classComment}")
public class ${classInfo.className}DTO {
<#if classInfo.fieldList?exists && classInfo.fieldList?size gt 0>
<#list classInfo.fieldList as fieldItem >
@ApiModelProperty("${fieldItem.fieldComment}")
private ${fieldItem.fieldClass} ${fieldItem.fieldName};
</#list>
public ${classInfo.className}() {
}
</#if>
}

View File

@@ -2,9 +2,10 @@
import java.util.List; import java.util.List;
/** /**
* ${classInfo.classComment} * @description ${classInfo.classComment}
* @author ${authorName} ${.now?string('yyyy-MM-dd')} * @author ${authorName}
*/ * @date ${.now?string('yyyy-MM-dd')}
*/
public interface I${classInfo.className}DAO { public interface I${classInfo.className}DAO {
int add(${classInfo.className} ${classInfo.className?uncap_first}); int add(${classInfo.className} ${classInfo.className?uncap_first});

View File

@@ -6,9 +6,10 @@ import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
/** /**
* ${classInfo.classComment} * @description ${classInfo.classComment}
* @author ${authorName} ${.now?string('yyyy-MM-dd')} * @author ${authorName}
*/ * @date ${.now?string('yyyy-MM-dd')}
*/
@Repository @Repository
public class ${classInfo.className}DaoImpl implements I${classInfo.className}Dao{ public class ${classInfo.className}DaoImpl implements I${classInfo.className}Dao{

View File

@@ -1,25 +1,39 @@
import java.io.Serializable; package ${packageName}.entity;
import javax.persistence.*;
import lombok.Data; import lombok.Data;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.GeneratedValue;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/** /**
* ${classInfo.classComment} * @description ${classInfo.classComment}
* @author ${authorName} ${.now?string('yyyy-MM-dd')} * @author ${authorName}
*/ * @date ${.now?string('yyyy-MM-dd')}
*/
@Entity @Entity
@Data @Data
@Table(name="${classInfo.tableName}") @Table(name="${classInfo.tableName}")<#if swagger?exists && swagger==true>
@ApiModel("${classInfo.classComment}")</#if>
public class ${classInfo.className} implements Serializable { public class ${classInfo.className} implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Id @Id
@GeneratedValue @GeneratedValue
<#if classInfo.fieldList?exists && classInfo.fieldList?size gt 0> <#if classInfo.fieldList?exists && classInfo.fieldList?size gt 0>
<#list classInfo.fieldList as fieldItem > <#list classInfo.fieldList as fieldItem >
/** /**
* ${fieldItem.fieldComment} * ${fieldItem.fieldComment}
*/ */<#if swagger?exists && swagger==true>
@ApiModelProperty("${fieldItem.fieldComment}")</#if>
@Column(name="${fieldItem.columnName}")
private ${fieldItem.fieldClass} ${fieldItem.fieldName}; private ${fieldItem.fieldClass} ${fieldItem.fieldName};
</#list> </#list>
@@ -27,4 +41,4 @@ public class ${classInfo.className} implements Serializable {
} }
</#if> </#if>
} }

View File

@@ -15,9 +15,10 @@ import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* ${classInfo.classComment} * @description ${classInfo.classComment}
* @author ${authorName} ${.now?string('yyyy-MM-dd')} * @author ${authorName}
*/ * @date ${.now?string('yyyy-MM-dd')}
*/
@RestController @RestController
@RequestMapping("/${classInfo.className?uncap_first}") @RequestMapping("/${classInfo.className?uncap_first}")
public class ${classInfo.className}Controller { public class ${classInfo.className}Controller {

View File

@@ -14,9 +14,10 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
/** /**
* ${classInfo.classComment} * @description ${classInfo.classComment}
* @author ${authorName} ${.now?string('yyyy-MM-dd')} * @author ${authorName}
*/ * @date ${.now?string('yyyy-MM-dd')}
*/
@Repository @Repository
public interface ${classInfo.className}Repository extends JpaRepository<${classInfo.className},Integer> { public interface ${classInfo.className}Repository extends JpaRepository<${classInfo.className},Integer> {

View File

@@ -1,19 +1,28 @@
package ${packageName}.controller; package ${packageName}.controller;
import com.alibaba.fastjson.JSON;
import ${packageName}.entity.${classInfo.className}; import ${packageName}.entity.${classInfo.className};
import ${packageName}.mapper.${classInfo.className}Mapper; import ${packageName}.mapper.${classInfo.className}Mapper;
import ${packageName}.util.ReturnT;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.web.servlet.ModelAndView;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* ${classInfo.classComment} * @description ${classInfo.classComment}
* @author ${authorName} ${.now?string('yyyy-MM-dd')} * @author ${authorName}
* @date ${.now?string('yyyy-MM-dd')}
*/ */
@Slf4j
@RestController @RestController
@RequestMapping("/${classInfo.className?uncap_first}") @RequestMapping("/${classInfo.className?uncap_first}")
public class ${classInfo.className}Controller { public class ${classInfo.className}Controller {
@@ -25,14 +34,20 @@ public class ${classInfo.className}Controller {
* 新增或编辑 * 新增或编辑
*/ */
@PostMapping("/save") @PostMapping("/save")
public Object save(${classInfo.className} ${classInfo.className?uncap_first}){ public Object save(@RequestBody ${classInfo.className} ${classInfo.className?uncap_first}){
${classInfo.className} ${classInfo.className?uncap_first} = ${classInfo.className?uncap_first}Mapper.selectOne(new QueryWrapper<${classInfo.className}>().eq("id",id)) log.info("${classInfo.className?uncap_first}:"+JSON.toJSONString(${classInfo.className?uncap_first}));
if(${classInfo.className?uncap_first}!=null){ ${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}.setUpdateTime(new Date());
if(old${classInfo.className}!=null){
${classInfo.className?uncap_first}Mapper.updateById(${classInfo.className?uncap_first}); ${classInfo.className?uncap_first}Mapper.updateById(${classInfo.className?uncap_first});
}else{ }else{
${classInfo.className?uncap_first}Mapper.insert(${classInfo.className?uncap_first}); 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 ${returnUtil}.ERROR("保存失败,名字重复");
} }
return ${returnUtil}.success(${classInfo.className?uncap_first}); ${classInfo.className?uncap_first}.setCreateTime(new Date());
${classInfo.className?uncap_first}Mapper.insert(${classInfo.className?uncap_first});
}
return ${returnUtil}.SUCCESS("保存成功");
} }
/** /**
@@ -40,11 +55,12 @@ public class ${classInfo.className}Controller {
*/ */
@PostMapping("/delete") @PostMapping("/delete")
public Object delete(int id){ public Object delete(int id){
${classInfo.className} ${classInfo.className?uncap_first} = ${classInfo.className?uncap_first}Mapper.selectOne(new QueryWrapper<${classInfo.className}>().eq("id",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){ if(${classInfo.className?uncap_first}!=null){
return ${returnUtil}.success(${classInfo.className?uncap_first}); ${classInfo.className?uncap_first}Mapper.deleteById(id);
return ${returnUtil}.SUCCESS("删除成功");
}else{ }else{
return ${returnUtil}.error("没有找到该对象"); return ${returnUtil}.ERROR("没有找到该对象");
} }
} }
@@ -53,29 +69,85 @@ public class ${classInfo.className}Controller {
*/ */
@PostMapping("/find") @PostMapping("/find")
public Object find(int id){ public Object find(int id){
${classInfo.className} ${classInfo.className?uncap_first} = ${classInfo.className?uncap_first}Mapper.selectOne(new QueryWrapper<${classInfo.className}>().eq("id",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){ if(${classInfo.className?uncap_first}!=null){
return ${returnUtil}.success(${classInfo.className?uncap_first}); return ${returnUtil}.SUCCESS(${classInfo.className?uncap_first});
}else{ }else{
return ${returnUtil}.error("没有找到该对象"); return ${returnUtil}.ERROR("没有找到该对象");
} }
} }
/** /**
* 分页查询 * 自动分页查询
*/ */
@PostMapping("/list") @PostMapping("/list")
public Object list(${classInfo.className} ${classInfo.className?uncap_first}, public Object list(String searchParams,
@RequestParam(required = false, defaultValue = "0") int pageNumber, @RequestParam(required = false, defaultValue = "0") int page,
@RequestParam(required = false, defaultValue = "10") int pageSize) { @RequestParam(required = false, defaultValue = "10") int limit) {
log.info("page:"+page+"-limit:"+limit+"-json:"+ JSON.toJSONString(searchParams));
//分页构造器 //分页构造器
Page<${classInfo.className}> page = new Page<${classInfo.className}>(pageNumber,pageSize); Page<${classInfo.className}> buildPage = new Page<${classInfo.className}>(page,limit);
//条件构造器 //条件构造器
QueryWrapper<${classInfo.className}> queryWrapperw = new QueryWrapper<${classInfo.className}>(${classInfo.className?uncap_first}); QueryWrapper<${classInfo.className}> queryWrapper = new QueryWrapper<${classInfo.className}>();
if(StringUtils.isNotEmpty(searchParams)&&JSON.isValid(searchParams)) {
${classInfo.className} ${classInfo.className?uncap_first} = JSON.parseObject(searchParams, ${classInfo.className}.class);
queryWrapper.eq(StringUtils.isNoneEmpty(${classInfo.className?uncap_first}.get${classInfo.className}Name()), "${classInfo.className?uncap_first}_name", ${classInfo.className?uncap_first}.get${classInfo.className}Name());
}
//执行分页 //执行分页
IPage<${classInfo.className}> pageList = certPersonMapper.selectPage(page, queryWrapperw); IPage<${classInfo.className}> pageList = ${classInfo.className?uncap_first}Mapper.selectPage(buildPage, queryWrapper);
//返回结果 //返回结果
return ${returnUtil}.success(pageList); 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

@@ -0,0 +1,35 @@
package ${packageName}.entity;
import lombok.Data;
import java.util.Date;
import java.util.List;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
/**
* @description ${classInfo.classComment}
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd')}
*/
@Data<#if swagger?exists && swagger==true>
@ApiModel("${classInfo.classComment}")</#if>
public class ${classInfo.className} implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.AUTO)
<#if classInfo.fieldList?exists && classInfo.fieldList?size gt 0>
<#list classInfo.fieldList as fieldItem >
/**
* ${fieldItem.fieldComment}
*/<#if swagger?exists && swagger==true>
@ApiModelProperty("${fieldItem.fieldComment}")</#if>
private ${fieldItem.fieldClass} ${fieldItem.fieldName};
</#list>
public ${classInfo.className}() {
}
</#if>
}

View File

@@ -1,14 +1,38 @@
package ${packageName}.mapper; package ${packageName}.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import ${packageName}.entity.${classInfo.className};
import java.util.List;
/** /**
* ${classInfo.classComment} * @description ${classInfo.classComment}
* @author ${authorName} ${.now?string('yyyy-MM-dd')} * @author ${authorName}
*/ * @date ${.now?string('yyyy-MM-dd')}
@Repository */
@Mapper
public interface ${classInfo.className}Mapper extends BaseMapper<${classInfo.className}> { public interface ${classInfo.className}Mapper extends BaseMapper<${classInfo.className}> {
@Select(
"<script>select t0.* from ${classInfo.tableName} t0 " +
//add here if need left join
"where 1=1" +
<#list classInfo.fieldList as fieldItem >
"<when test='${fieldItem.fieldName}!=null and ${fieldItem.fieldName}!=&apos;&apos; '> and t0.${fieldItem.columnName}=井{${fieldItem.fieldName}}</when> " +
</#list>
//add here if need page limit
//" limit ¥{page},¥{limit} " +
" </script>")
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
"where 1=1" +
<#list classInfo.fieldList as fieldItem >
"<when test='${fieldItem.fieldName}!=null and ${fieldItem.fieldName}!=&apos;&apos; '> and t0.${fieldItem.columnName}=井{${fieldItem.fieldName}}</when> " +
</#list>
" </script>")
int countAll(${classInfo.className} queryParamDTO);
} }

View File

@@ -9,10 +9,10 @@ import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* ${classInfo.classComment} * @description ${classInfo.classComment}
* @author ${authorName} * @author ${authorName}
* @date ${.now?string('yyyy/MM/dd')} * @date ${.now?string('yyyy-MM-dd')}
*/ */
@RestController @RestController
@RequestMapping(value = "/${classInfo.className}") @RequestMapping(value = "/${classInfo.className}")
public class ${classInfo.className}Controller { public class ${classInfo.className}Controller {
@@ -21,7 +21,7 @@ public class ${classInfo.className}Controller {
private ${classInfo.className}Service ${classInfo.className?uncap_first}Service; private ${classInfo.className}Service ${classInfo.className?uncap_first}Service;
/** /**
* [新增] * 新增
* @author ${authorName} * @author ${authorName}
* @date ${.now?string('yyyy/MM/dd')} * @date ${.now?string('yyyy/MM/dd')}
**/ **/
@@ -31,7 +31,7 @@ public class ${classInfo.className}Controller {
} }
/** /**
* [刪除] * 刪除
* @author ${authorName} * @author ${authorName}
* @date ${.now?string('yyyy/MM/dd')} * @date ${.now?string('yyyy/MM/dd')}
**/ **/
@@ -41,7 +41,7 @@ public class ${classInfo.className}Controller {
} }
/** /**
* [更新] * 更新
* @author ${authorName} * @author ${authorName}
* @date ${.now?string('yyyy/MM/dd')} * @date ${.now?string('yyyy/MM/dd')}
**/ **/
@@ -51,7 +51,7 @@ public class ${classInfo.className}Controller {
} }
/** /**
* [查询] 根据主键 id 查询 * 查询 根据主键 id 查询
* @author ${authorName} * @author ${authorName}
* @date ${.now?string('yyyy/MM/dd')} * @date ${.now?string('yyyy/MM/dd')}
**/ **/
@@ -61,7 +61,7 @@ public class ${classInfo.className}Controller {
} }
/** /**
* [查询] 分页查询 * 查询 分页查询
* @author ${authorName} * @author ${authorName}
* @date ${.now?string('yyyy/MM/dd')} * @date ${.now?string('yyyy/MM/dd')}
**/ **/

View File

@@ -4,51 +4,51 @@ import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
/** /**
* ${classInfo.classComment} * @description ${classInfo.classComment}
* @author ${authorName} * @author ${authorName}
* @date ${.now?string('yyyy/MM/dd')} * @date ${.now?string('yyyy-MM-dd')}
*/ */
@Mapper @Mapper
@Repository @Repository
public interface ${classInfo.className}Mapper { public interface ${classInfo.className}Mapper {
/** /**
* [新增] * 新增
* @author ${authorName} * @author ${authorName}
* @date ${.now?string('yyyy/MM/dd')} * @date ${.now?string('yyyy/MM/dd')}
**/ **/
int insert(${classInfo.className} ${classInfo.className?uncap_first}); int insert(${classInfo.className} ${classInfo.className?uncap_first});
/** /**
* [刪除] * 刪除
* @author ${authorName} * @author ${authorName}
* @date ${.now?string('yyyy/MM/dd')} * @date ${.now?string('yyyy/MM/dd')}
**/ **/
int delete(int id); int delete(int id);
/** /**
* [更新] * 更新
* @author ${authorName} * @author ${authorName}
* @date ${.now?string('yyyy/MM/dd')} * @date ${.now?string('yyyy/MM/dd')}
**/ **/
int update(${classInfo.className} ${classInfo.className?uncap_first}); int update(${classInfo.className} ${classInfo.className?uncap_first});
/** /**
* [查询] 根据主键 id 查询 * 查询 根据主键 id 查询
* @author ${authorName} * @author ${authorName}
* @date ${.now?string('yyyy/MM/dd')} * @date ${.now?string('yyyy/MM/dd')}
**/ **/
${classInfo.className} load(int id); ${classInfo.className} load(int id);
/** /**
* [查询] 分页查询 * 查询 分页查询
* @author ${authorName} * @author ${authorName}
* @date ${.now?string('yyyy/MM/dd')} * @date ${.now?string('yyyy/MM/dd')}
**/ **/
List<${classInfo.className}> pageList(int offset,int pagesize); List<${classInfo.className}> pageList(int offset,int pagesize);
/** /**
* [查询] 分页查询 count * 查询 分页查询 count
* @author ${authorName} * @author ${authorName}
* @date ${.now?string('yyyy/MM/dd')} * @date ${.now?string('yyyy/MM/dd')}
**/ **/

View File

@@ -0,0 +1,56 @@
package ${packageName}.mapper;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @description ${classInfo.classComment}Mapper
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd')}
*/
@Mapper
@Repository
public interface ${classInfo.className}Mapper {
@Select("select * from ${classInfo.tableName} where ${classInfo.tableName}_id=井{id}")
public ${classInfo.className} getById(Integer id);
@Options(useGeneratedKeys=true,keyProperty="${classInfo.className?uncap_first}Id")
@Insert("insert into ${classInfo.tableName}"
"(<#list classInfo.fieldList as fieldItem >${fieldItem.columnName}<#if fieldItem_has_next>,</#if></#list>)"
"values(<#list classInfo.fieldList as fieldItem >${fieldItem.fieldName}<#if fieldItem_has_next>,</#if>)</#list>")
public Integer insert(${classInfo.className} ${classInfo.className?uncap_first});
@Delete(value = "delete from ${classInfo.tableName} where ${classInfo.tableName}_id=井{${classInfo.className?uncap_first}Id}")
boolean delete(Integer id);
@Update(value = "update ${classInfo.tableName} set "
<#list classInfo.fieldList as fieldItem >
<#if fieldItem.columnName != "id">+" ${fieldItem.columnName}=井{${fieldItem.fieldName}}<#if fieldItem_has_next>,</#if>"</#if>
</#list>
+" where ${classInfo.tableName}_id=井{${classInfo.className?uncap_first}Id} ")
boolean update(${classInfo.className} ${classInfo.className?uncap_first});
@Results(value = {
<#list classInfo.fieldList as fieldItem >
@Result(property = "${fieldItem.fieldName}", column = "${fieldItem.columnName}")<#if fieldItem_has_next>,</#if>
</#list>
})
@Select(value = "select * from ${classInfo.tableName} where ${classInfo.tableName}_id=井{queryParam}")
${classInfo.className} selectOne(String queryParam);
@Results(value = {
<#list classInfo.fieldList as fieldItem >
@Result(property = "${fieldItem.fieldName}", column = "${fieldItem.columnName}")<#if fieldItem_has_next>,</#if>
</#list>
})
@Select(value = "select * from ${classInfo.tableName} where "
<#list classInfo.fieldList as fieldItem >
+" ${fieldItem.columnName}=井{${fieldItem.fieldName}}<#if fieldItem_has_next> or </#if>"
</#list>
)
List<${classInfo.className}> selectList(${classInfo.className} ${classInfo.className?uncap_first});
}

View File

@@ -3,10 +3,12 @@ import java.util.Date;
import java.util.List; import java.util.List;
/** /**
* ${classInfo.classComment} * @description ${classInfo.classComment}
* @author ${authorName} ${.now?string('yyyy-MM-dd')} * @author ${authorName}
*/ * @date ${.now?string('yyyy-MM-dd')}
*/
public class ${classInfo.className} implements Serializable { public class ${classInfo.className} implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
<#if classInfo.fieldList?exists && classInfo.fieldList?size gt 0> <#if classInfo.fieldList?exists && classInfo.fieldList?size gt 0>
@@ -34,4 +36,4 @@ public class ${classInfo.className} implements Serializable {
</#list> </#list>
</#if> </#if>
} }

View File

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

View File

@@ -7,10 +7,10 @@ import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* ${classInfo.classComment} * @description ${classInfo.classComment}
* @author ${authorName} * @author ${authorName}
* @date ${.now?string('yyyy/MM/dd')} * @date ${.now?string('yyyy-MM-dd')}
*/ */
@Service @Service
public class ${classInfo.className}ServiceImpl implements ${classInfo.className}Service { public class ${classInfo.className}ServiceImpl implements ${classInfo.className}Service {
@@ -23,25 +23,25 @@ public class ${classInfo.className}ServiceImpl implements ${classInfo.className}
// valid // valid
if (${classInfo.className?uncap_first} == null) { 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}); ${classInfo.className?uncap_first}Mapper.insert(${classInfo.className?uncap_first});
return ReturnT.SUCCESS; return ${returnUtil}.SUCCESS;
} }
@Override @Override
public ReturnT<String> delete(int id) { public ReturnT<String> delete(int id) {
int ret = ${classInfo.className?uncap_first}Mapper.delete(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 @Override
public ReturnT<String> update(${classInfo.className} ${classInfo.className?uncap_first}) { public ReturnT<String> update(${classInfo.className} ${classInfo.className?uncap_first}) {
int ret = ${classInfo.className?uncap_first}Mapper.update(${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

@@ -0,0 +1,78 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>layuimini</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="¥{request.contextPath}/static/lib/layui-v2.5.5/css/layui.css" media="all">
<link rel="stylesheet" href="¥{request.contextPath}/static/css/public.css" media="all">
<style>
body {
background-color: #ffffff;
}
</style>
</head>
<body>
<div class="layui-form layuimini-form">
<input type="hidden" name="${classInfo.className?uncap_first}Id" value="" class="layui-input">
<#if classInfo.fieldList?exists && classInfo.fieldList?size gt 0>
<#list classInfo.fieldList as fieldItem >
<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="¥{(${classInfo.className?uncap_first}.${fieldItem.fieldName})!!}" class="layui-input">
<#--<tip>${fieldItem.fieldComment}</tip>-->
</div>
</div>
</#list>
</#if>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="saveBtn">确认保存</button>
</div>
</div>
</div>
</div>
<script src="¥{request.contextPath}/static/lib/layui-v2.5.5/layui.js" charset="utf-8"></script>
<script>
layui.use(['form'], function () {
var form = layui.form,
layer = layui.layer,
$ = layui.$;
//监听提交
form.on('submit(saveBtn)', function (data) {
$.ajax({
type: 'POST',
url: "¥{request.contextPath}/${classInfo.className?uncap_first}/save",
data:JSON.stringify(data.field),
dataType: "json",
contentType: "application/json",
success: function (responseData) {
if (responseData.code === 200) {
layer.msg(responseData.msg, function () {
// 关闭弹出层
//layer.close(index);
var iframeIndex = parent.layer.getFrameIndex(window.name);
parent.layer.close(iframeIndex);
parent.searchBtn.click();
});
} else {
layer.msg(responseData.msg, function () {
//window.location = '/index.html';
});
}
}
});
return false;
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,230 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>layuimini</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="¥{request.contextPath}/static/lib/layui-v2.5.5/css/layui.css" media="all">
<link rel="stylesheet" href="¥{request.contextPath}/static/css/public.css" media="all">
</head>
<body>
<div class="layuimini-container">
<div class="layuimini-main">
<fieldset class="table-search-fieldset">
<legend>搜索信息</legend>
<div style="margin: 10px 10px 10px 10px">
<form class="layui-form layui-form-pane" action="">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">${classInfo.classComment}Id</label>
<div class="layui-input-inline">
<input type="text" name="${classInfo.className?uncap_first}Id" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">${classInfo.classComment}名称</label>
<div class="layui-input-inline">
<input type="text" name="${classInfo.className?uncap_first}Name" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<button id="searchBtn" type="submit" class="layui-btn layui-btn-primary" lay-submit lay-filter="data-search-btn"><i class="layui-icon"></i> 搜 索</button>
</div>
</div>
</form>
</div>
</fieldset>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<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>
<table class="layui-hide" id="currentTableId" lay-filter="currentTableFilter"></table>
<script type="text/html" id="currentTableBar">
<a class="layui-btn layui-btn-xs data-count-edit" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-xs layui-btn-danger data-count-delete" lay-event="delete">删除</a>
</script>
<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>
</div>
<script src="¥{request.contextPath}/static/lib/layui-v2.5.5/layui.js" charset="utf-8"></script>
<script>
layui.use(['form', 'table'], function () {
var $ = layui.jquery,
form = layui.form,
table = layui.table;
table.render({
elem: '#currentTableId',
method: 'post',
url: '¥{request.contextPath}/${classInfo.className?uncap_first}/list',
toolbar: '#toolbarDemo',
defaultToolbar: ['filter', 'exports', 'print', {
title: '提示',
layEvent: 'LAYTABLE_TIPS',
icon: 'layui-icon-tips'
}],
cols: [[
{type: "checkbox", width: 50, fixed: "left"},
<#if classInfo.fieldList?exists && classInfo.fieldList?size gt 0>
<#list classInfo.fieldList as fieldItem >
{field: '${fieldItem.fieldName}', title: '${fieldItem.fieldComment}', sort: true}, <#if fieldItem_has_next> </#if>
</#list>
</#if>
/* 需要时间请自行解封
{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: [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);
//执行搜索重载
table.reload('currentTableId', {
page: {
curr: 1
}
, where: {
searchParams: result
}
}, 'data');
return false;
});
var searchBtn = $("#searchBtn");
/**
* toolbar监听事件:表格添加按钮
*/
table.on('toolbar(currentTableFilter)', function (obj) {
if (obj.event === 'add') {
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=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,
});
return false;
} else if (obj.event === 'delete') {
layer.confirm('确认删除该记录吗?', function (index) {
$.ajax({
type: 'POST',
url: "¥{request.contextPath}/${classInfo.className?uncap_first}/delete",
data:{"id":obj.data.${classInfo.className?uncap_first}Id},
success: function (responseData) {
if (responseData.code === 200) {
layer.msg(responseData.msg, function () {
obj.del();
});
} else {
layer.msg(responseData.msg, function () {
});
}
}
});
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);
});
}
});
});
</script>
<script>
</script>
</body>
</html>

View File

@@ -1,331 +1,425 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>SQL转Java JPA、MYBATIS实现类代码生成平台</title> <title>SQL转Java JPA、MYBATIS实现类代码生成平台</title>
<meta name="keywords" content="sql转实体类,sql转DAO,SQL转service,SQL转JPA实现,SQL转MYBATIS实现"> <meta name="keywords" content="sql转实体类,sql转DAO,SQL转service,SQL转JPA实现,SQL转MYBATIS实现">
<#import "common/common-import.ftl" as netCommon> <#import "common/common-import.ftl" as netCommon>
<@netCommon.commonStyle /> <@netCommon.commonStyle />
<@netCommon.commonScript /> <@netCommon.commonScript />
<script> <script>
<@netCommon.viewerCounter /> <@netCommon.viewerCounter />
$(function () { $(function () {
/** /**
* 初始化 table sql 3 * 初始化 table sql 3
*/ */
var ddlSqlArea = CodeMirror.fromTextArea(document.getElementById("ddlSqlArea"), { var ddlSqlArea = CodeMirror.fromTextArea(document.getElementById("ddlSqlArea"), {
lineNumbers: true, lineNumbers: true,
matchBrackets: true, matchBrackets: true,
mode: "text/x-sql", mode: "text/x-sql",
lineWrapping:false, lineWrapping:false,
readOnly:false, readOnly:false,
foldGutter: true, foldGutter: true,
//keyMap:"sublime", //keyMap:"sublime",
gutters:["CodeMirror-linenumbers", "CodeMirror-foldgutter"] gutters:["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
}); });
ddlSqlArea.setSize('auto','auto'); ddlSqlArea.setSize('auto','auto');
// controller_ide // controller_ide
var genCodeArea = CodeMirror.fromTextArea(document.getElementById("genCodeArea"), { var genCodeArea = CodeMirror.fromTextArea(document.getElementById("genCodeArea"), {
lineNumbers: true, lineNumbers: true,
matchBrackets: true, matchBrackets: true,
mode: "text/x-java", mode: "text/x-java",
lineWrapping:true, lineWrapping:true,
readOnly:false, readOnly:false,
foldGutter: true, foldGutter: true,
//keyMap:"sublime", //keyMap:"sublime",
gutters:["CodeMirror-linenumbers", "CodeMirror-foldgutter"] gutters:["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
}); });
genCodeArea.setSize('auto','auto'); genCodeArea.setSize('auto','auto');
var codeData; var codeData;
// 使用var jsonObj = $("#formId").serializeObject();
/** $.fn.serializeObject = function()
* 生成代码 {
*/ var o = {};
$('#btnGenCode').click(function () { var a = this.serializeArray();
var tableSql = ddlSqlArea.getValue(); $.each(a, function() {
$.ajax({ if (o[this.name]) {
type: 'POST', if (!o[this.name].push) {
url: base_url + "/genCode", o[this.name] = [o[this.name]];
data: { }
"tableSql": tableSql, o[this.name].push(this.value || '');
"packageName":$("#packageName").val(), } else {
"returnUtil":$("#returnUtil").val(), o[this.name] = this.value || '';
"authorName":$("#authorName").val(), }
"dataType":$("#dataType").val(), });
"tinyintTransType":$("#tinyintTransType").val(), return o;
"nameCaseType":$("#nameCaseType").val() };
}, var historyCount=0;
dataType: "json", //初始化清除session
success: function (data) { if (window.sessionStorage){
if (data.code == 200) { //修复当F5刷新的时候session没有清空各个值但是页面的button没了。
codeData = data.data; sessionStorage.clear();
genCodeArea.setValue(codeData.beetlentity); }
genCodeArea.setSize('auto', 'auto'); /**
$.toast("√ 代码生成成功"); * 生成代码
} else { */
$.toast("× 代码生成失败 :"+data.msg); $('#btnGenCode').click(function () {
} var jsonData = {
} "tableSql": ddlSqlArea.getValue(),
}); "packageName":$("#packageName").val(),
}); "returnUtil":$("#returnUtil").val(),
/** "authorName":$("#authorName").val(),
* 按钮事件组 "dataType":$("#dataType").val(),
*/ "tinyintTransType":$("#tinyintTransType").val(),
$('.generator').bind('click', function () { "nameCaseType":$("#nameCaseType").val(),
if (!$.isEmptyObject(codeData)) { "swagger":$("#isSwagger").val()
var id = this.id; };
genCodeArea.setValue(codeData[id]); $.ajax({
genCodeArea.setSize('auto', 'auto'); type: 'POST',
} url: base_url + "/genCode",
}); data:(JSON.stringify(jsonData)),
/** dataType: "json",
* 捐赠 contentType: "application/json",
*/ success: function (data) {
function donate(){ if (data.code === 200) {
if($("#donate").attr("show")=="no"){ codeData = data.data;
$("#donate").html('<img src="http://upyun.bejson.com/img/zhengkai.png"></img>'); genCodeArea.setValue(codeData.beetlentity);
$("#donate").attr("show","yes"); genCodeArea.setSize('auto', 'auto');
}else{ $.toast("√ 代码生成成功");
$("#donate").html('<p>谢谢赞赏!</p>'); //添加历史记录
$("#donate").attr("show","no"); addHistory(codeData);
} } else {
} $.toast("× 代码生成失败 :"+data.msg);
$('#donate1').on('click', function(){ }
donate(); }
}); });
$('#donate2').on('click', function(){ return false;
donate(); });
}); /**
$('#btnCopy').on('click', function(){ * 切换历史记录
if(!$.isEmptyObject(genCodeArea.getValue())&&!$.isEmptyObject(navigator)&&!$.isEmptyObject(navigator.clipboard)){ */
navigator.clipboard.writeText(genCodeArea.getValue()); function getHistory(tableName){
$.toast("√ 复制成功"); if (window.sessionStorage){
} var valueSession = sessionStorage.getItem(tableName);
}); codeData = JSON.parse(valueSession);
$.toast("$ 切换历史记录成功:"+tableName);
}); genCodeArea.setValue(codeData.entity);
</script> }else{
</head> console.log("浏览器不支持sessionStorage");
<body style="background-color: #e9ecef"> }
}
<div class="container"> /**
<nav class="navbar navbar-dark bg-primary btn-lg"> * 添加历史记录
<a class="navbar-brand" href="http://www.bejson.com">BeJSON在线工具站</a> */
<ul class="nav navbar-nav"> function addHistory(data){
<li class="nav-item active"> if (window.sessionStorage){
<a class="nav-link" href="http://zhengkai.blog.csdn.net">大狼狗CSDN</a> //console.log(historyCount);
</li> if(historyCount>=9){
</ul> $("#history").find(".btn:last").remove();
</nav> historyCount--;
</div> }
var tableName=data.tableName;
<!-- Main jumbotron for a primary marketing message or call to action --> var valueSession = sessionStorage.getItem(tableName);
<div class="jumbotron"> if(valueSession!==undefined && valueSession!=null){
<div class="container"> sessionStorage.removeItem(tableName);
<h2>Spring Boot Code Generator!</h2> }else{
<p class="lead"> $("#history").prepend('<button id="his-'+tableName+'" type="button" class="btn">'+tableName+'</button>');
√基于SpringBoot2+Freemarker的代码生成器√以释放双手为目的√支持mysql/oracle/pgsql三大数据库<br> //$("#history").prepend('<button id="his-'+tableName+'" onclick="getHistory(\''+tableName+'\');" type="button" class="btn">'+tableName+'</button>');
√用DDL-SQL语句生成JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL相关代码。<br> $("#his-"+tableName).bind('click', function () {getHistory(tableName)});
欢迎大家多多提交模板和交流想法如果发现有SQL语句不能识别请<a href="https://github.com/moshowgame/SpringBootCodeGenerator/issues">留言</a>,同时欢迎大家提<a href="https://github.com/moshowgame/SpringBootCodeGenerator/pulls">PR</a>和<a href="#" id="donate1">点击赞赏</a>,谢谢! }
</p> sessionStorage.setItem(tableName,JSON.stringify(data));
<div id="donate" class="container" show="no"></div> historyCount++;
<hr> }else{
<div class="input-group mb-3"> console.log("浏览器不支持sessionStorage");
<div class="input-group-prepend"> }
<span class="input-group-text">作者名称</span> }
</div>
<input type="text" class="form-control" id="authorName" name="authorName" placeholder="大狼狗"> /**
<div class="input-group-prepend"> * 按钮事件组
<span class="input-group-text">返回封装</span> */
</div> $('.generator').bind('click', function () {
<input type="text" class="form-control" id="returnUtil" name="returnUtil" placeholder="ApiReturnObject"> if (!$.isEmptyObject(codeData)) {
<div class="input-group-prepend"> var id = this.id;
<span class="input-group-text">包名路径</span> genCodeArea.setValue(codeData[id]);
</div> genCodeArea.setSize('auto', 'auto');
<input type="text" class="form-control" id="packageName" name="packageName" placeholder="com.softdev.system"> }
</div> });
<div class="input-group mb-3"> /**
<div class="input-group-prepend"> * 捐赠
<span class="input-group-text">数据类型</span> */
</div> function donate(){
<select type="text" class="form-control" id="dataType" if($("#donate").attr("show")=="no"){
name="dataType"> $("#donate").html('<img src="https://raw.githubusercontent.com/moshowgame/SpringBootCodeGenerator/master/donate.png"></img>');
<option value="sql">sql</option> $("#donate").attr("show","yes");
<option value="json">json</option> }else{
<option value="sql-regex">sql-regex</option> $("#donate").html('<p>谢谢赞赏!</p>');
</select> $("#donate").attr("show","no");
<div class="input-group-prepend"> }
<span class="input-group-text">tinyint转换类型</span> }
</div> $('#donate1').on('click', function(){
<select type="text" class="form-control" id="tinyintTransType" donate();
name="tinyintTransType"> });
<option value="boolean">boolean</option> $('#donate2').on('click', function(){
<option value="Boolean">Boolean</option> donate();
<option value="Integer">Integer</option> });
<option value="int">int</option> $('#btnCopy').on('click', function(){
<option value="String">String</option> if(!$.isEmptyObject(genCodeArea.getValue())&&!$.isEmptyObject(navigator)&&!$.isEmptyObject(navigator.clipboard)){
</select> navigator.clipboard.writeText(genCodeArea.getValue());
<div class="input-group-prepend"> $.toast("√ 复制成功");
<span class="input-group-text">命名转换规则</span> }
</div> });
<select type="text" class="form-control" id="nameCaseType"
name="nameCaseType"> function getVersion(){
<option value="CamelCase">驼峰</option> var gitVersion ;
<option value="UnderScoreCase">下划线</option> $.ajax({
<#--<option value="UpperUnderScoreCase">大写下划线</option>--> type: 'GET',
</select> url: "https://raw.githubusercontent.com/moshowgame/SpringBootCodeGenerator/master/generator-web/src/main/resources/static/version.json",
</div> dataType: "json",
<textarea id="ddlSqlArea" placeholder="请输入表结构信息..." class="form-control btn-lg" style="height: 250px;"> success: function (data) {
CREATE TABLE 'userinfo' ( gitVersion = data.version;
'user_id' int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID', $.ajax({
'username' varchar(255) NOT NULL COMMENT '用户名', type: 'GET',
'addtime' datetime NOT NULL COMMENT '创建时间', url: base_url + "/static/version.json",
PRIMARY KEY ('user_id') dataType: "json",
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户信息' success: function (data) {
</textarea><br> $.toast("#当前版本:"+data.version+" | github:"+gitVersion);
<p><button class="btn btn-primary btn-lg disabled" id="btnGenCode" role="button" data-toggle="popover" data-content="">开始生成 »</button> <button class="btn alert-secondary" id="btnCopy">一键复制</button></p> }
<hr> });
<!-- Example row of columns --> }
<div class="row" style="margin-top: 10px;"> });
<div class="btn-toolbar col-md-5" role="toolbar" aria-label="Toolbar with button groups"> }
<div class="input-group"> $('#version').on('click', function(){
<div class="input-group-prepend"> getVersion();
<div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">通用实体</div> });
</div> });
</div> </script>
<div class="btn-group" role="group" aria-label="First group"> </head>
<button type="button" class="btn btn-default generator" id="model">entity(set/get)</button> <body style="background-color: #e9ecef">
<button type="button" class="btn btn-default generator" id="beetlentity">entity(lombok)</button>
</div> <div class="container">
</div> <nav class="navbar navbar-dark bg-primary btn-lg">
<div class="btn-toolbar col-md-7" role="toolbar" aria-label="Toolbar with button groups"> <a class="navbar-brand" href="http://www.bejson.com">BeJSON在线工具站</a>
<div class="input-group"> <ul class="nav navbar-nav">
<div class="input-group-prepend"> <li class="nav-item active">
<div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">Mybatis</div> <a class="nav-link" href="http://zhengkai.blog.csdn.net">zhengkai.blog.csdn.net</a>
</div> </li>
</div> </ul>
<div class="btn-group" role="group" aria-label="First group"> </nav>
<button type="button" class="btn btn-default generator" id="mybatis">mybatis</button> </div>
<button type="button" class="btn btn-default generator" id="mapper">mapper</button>
<button type="button" class="btn btn-default generator" id="service">service</button> <!-- Main jumbotron for a primary marketing message or call to action -->
<button type="button" class="btn btn-default generator" id="service_impl">service_impl</button> <div class="jumbotron">
<button type="button" class="btn btn-default generator" id="controller">controller</button> <div class="container">
</div> <h2>Spring Boot Code Generator!</h2>
</div> <p class="lead">
</div> √基于SpringBoot2+Freemarker的<a class="lead" href="https://github.com/moshowgame/SpringBootCodeGenerator">代码生成器</a><br>
<!-- Example row of columns --> √以解放双手为目的减少大量重复的CRUD工作<br>
<div class="row" style="margin-top: 10px;"> √支持mysql/oracle/pgsql三大数据库<br>
<div class="btn-toolbar col-md-5" role="toolbar" aria-label="Toolbar with button groups"> √用DDL-SQL语句生成JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL相关代码。<br>
<div class="input-group"> 如果发现有SQL语句不能识别请<a href="https://github.com/moshowgame/SpringBootCodeGenerator/issues">留言</a>,同时欢迎大家提<a href="https://github.com/moshowgame/SpringBootCodeGenerator/pulls">PR</a>和<a href="#" id="donate1">赞赏</a>,谢谢!<a id="version" href="#">查看版本</a>
<div class="input-group-prepend"> </p>
<div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">MybatisPlus</div> <div id="donate" class="container" show="no"></div>
</div> <hr>
</div> <div class="input-group mb-3">
<div class="btn-group" role="group" aria-label="First group"> <div class="input-group-prepend">
<button type="button" class="btn btn-default generator" id="plusmapper">mapper</button> <span class="input-group-text">作者名称</span>
<button type="button" class="btn btn-default generator" id="pluscontroller">controller</button> </div>
</div> <input type="text" class="form-control" id="authorName" name="authorName" value="zhengkai.blog.csdn.net">
</div> <div class="input-group-prepend">
<span class="input-group-text">返回封装</span>
<div class="btn-toolbar col-md-5" role="toolbar" aria-label="Toolbar with button groups"> </div>
<div class="input-group"> <input type="text" class="form-control" id="returnUtil" name="returnUtil" value="ReturnT">
<div class="input-group-prepend"> <div class="input-group-prepend">
<div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">UI</div> <span class="input-group-text">包名路径</span>
</div> </div>
</div> <input type="text" class="form-control" id="packageName" name="packageName" value="com.softdev.system">
<div class="btn-group" role="group" aria-label="First group"> </div>
<button type="button" class="btn btn-default generator" id="swagger-ui">swagger-ui</button> <div class="input-group mb-3">
<button type="button" class="btn btn-default generator" id="element-ui">element-ui</button> <div class="input-group-prepend">
<button type="button" class="btn btn-default generator" id="bootstrap-ui">bootstrap-ui</button> <span class="input-group-text">数据类型</span>
</div> </div>
</div> <select type="text" class="form-control" id="dataType"
</div> name="dataType">
<option value="sql">ddl-sql</option>
<div class="row" style="margin-top: 10px;"> <option value="json">json</option>
<div class="btn-toolbar col-md-5" role="toolbar" aria-label="Toolbar with button groups"> <option value="insert-sql">insert-sql</option>
<div class="input-group"> <#--<option value="sql-regex">sql-regex</option>-->
<div class="input-group-prepend"> </select>
<div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">BeetlSQL</div> <div class="input-group-prepend">
</div> <span class="input-group-text">tinyint转换类型</span>
</div> </div>
<div class="btn-group" role="group" aria-label="First group"> <select type="text" class="form-control" id="tinyintTransType"
<button type="button" class="btn btn-default generator" id="beetlmd">beetlmd</button> name="tinyintTransType">
<button type="button" class="btn btn-default generator" id="beetlcontroller">beetlcontroller</button> <option value="boolean">boolean</option>
</div> <option value="Boolean">Boolean</option>
</div> <option value="Integer">Integer</option>
<div class="btn-toolbar col-md-5" role="toolbar" aria-label="Toolbar with button groups"> <option value="int">int</option>
<div class="input-group"> <option value="String">String</option>
<div class="input-group-prepend"> </select>
<div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">JPA</div> <div class="input-group-prepend">
</div> <span class="input-group-text">命名转换规则</span>
</div> </div>
<div class="btn-group" role="group" aria-label="First group"> <select type="text" class="form-control" id="nameCaseType"
<button type="button" class="btn btn-default generator" id="entity">jpa-entity</button> name="nameCaseType">
<button type="button" class="btn btn-default generator" id="repository">repository</button> <option value="CamelCase">驼峰</option>
<button type="button" class="btn btn-default generator" id="jpacontroller">controller</button> <option value="UnderScoreCase">下划线</option>
</div> <#--<option value="UpperUnderScoreCase">大写下划线</option>-->
</div> </select>
</div> <div class="input-group-prepend">
<div class="row" style="margin-top: 10px;"> <span class="input-group-text">swagger-ui</span>
<div class="btn-toolbar col-md-5" role="toolbar" aria-label="Toolbar with button groups"> </div>
<div class="input-group"> <select type="text" class="form-control" id="isSwagger"
<div class="input-group-prepend"> name="isSwagger">
<div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">JdbcTemplate</div> <option value="false">关闭</option>
</div> <option value="true">开启</option>
</div> </select>
<div class="btn-group" role="group" aria-label="First group"> </div>
<button type="button" class="btn btn-default generator" id="jtdaoimpl">daoimpl</button> <textarea id="ddlSqlArea" placeholder="请输入表结构信息..." class="form-control btn-lg" style="height: 250px;">
<button type="button" class="btn btn-default generator" id="jtdao">dao</button> CREATE TABLE 'userinfo' (
</div> 'user_id' int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
</div> 'user_name' varchar(255) NOT NULL COMMENT '用户名',
<div class="btn-toolbar col-md-7" role="toolbar" aria-label="Toolbar with button groups"> 'addtime' datetime NOT NULL COMMENT '创建时间',
<div class="input-group"> PRIMARY KEY ('user_id')
<div class="input-group-prepend"> ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户信息'
<div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">SQL</div> </textarea><br>
</div> <p><button class="btn btn-primary btn-lg disabled" id="btnGenCode" role="button" data-toggle="popover" data-content="">开始生成 »</button> <button class="btn alert-secondary" id="btnCopy">一键复制</button></p>
</div> <div id="history" class="btn-group" role="group" aria-label="Basic example"></div>
<div class="btn-group" role="group" aria-label="First group"> <hr>
<button type="button" class="btn btn-default generator" id="select">select</button> <!-- Example row of columns -->
<button type="button" class="btn btn-default generator" id="insert">insert</button> <div class="row" style="margin-top: 10px;">
<button type="button" class="btn btn-default generator" id="update">update</button> <div class="btn-toolbar col-md-5" role="toolbar" aria-label="Toolbar with button groups">
<button type="button" class="btn btn-default generator" id="delete">delete</button> <div class="input-group">
</div> <div class="input-group-prepend">
</div> <div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">通用实体</div>
</div> </div>
<div class="row" style="margin-top: 10px;"> </div>
<div class="btn-toolbar col-md-5" role="toolbar" aria-label="Toolbar with button groups"> <div class="btn-group" role="group" aria-label="First group">
<div class="input-group"> <button type="button" class="btn btn-default generator" id="model">entity(set/get)</button>
<div class="input-group-prepend"> <button type="button" class="btn btn-default generator" id="beetlentity">entity(lombok)</button>
<div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">DTO</div> </div>
</div> </div>
</div> <div class="btn-toolbar col-md-7" role="toolbar" aria-label="Toolbar with button groups">
<div class="btn-group" role="group" aria-label="First group"> <div class="input-group">
<button type="button" class="btn btn-default generator" id="beetlentitydto">entitydto(lombok+swagger)</button> <div class="input-group-prepend">
</div> <div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">Mybatis</div>
</div> </div>
<div class="btn-toolbar col-md-5" role="toolbar" aria-label="Toolbar with button groups"> </div>
<div class="input-group"> <div class="btn-group" role="group" aria-label="First group">
<div class="input-group-prepend"> <button type="button" class="btn btn-default generator" id="mybatis">ibatisXml</button>
<div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">Util</div> <button type="button" class="btn btn-default generator" id="mapper">mapper</button>
</div> <button type="button" class="btn btn-default generator" id="mapper2">mapper2</button>
</div> <button type="button" class="btn btn-default generator" id="service">service</button>
<div class="btn-group" role="group" aria-label="First group"> <button type="button" class="btn btn-default generator" id="service_impl">serviceImpl</button>
<button type="button" class="btn btn-default generator" id="util">bean get set</button> <button type="button" class="btn btn-default generator" id="controller">controller</button>
<button type="button" class="btn btn-default generator" id="json">json</button> </div>
<button type="button" class="btn btn-default generator" id="xml">xml</button> </div>
</div> </div>
</div> <!-- Example row of columns -->
</div> <div class="row" style="margin-top: 10px;">
<hr> <div class="btn-toolbar col-md-5" role="toolbar" aria-label="Toolbar with button groups">
<textarea id="genCodeArea" class="form-control btn-lg" ></textarea> <div class="input-group">
</div> <div class="input-group-prepend">
</div> <div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">MybatisPlus</div>
</div>
<@netCommon.commonFooter /> </div>
</body> <div class="btn-group" role="group" aria-label="First group">
</html> <button type="button" class="btn btn-default generator" id="plusentity">entity</button>
<button type="button" class="btn btn-default generator" id="plusmapper">mapper</button>
<button type="button" class="btn btn-default generator" id="pluscontroller">controller</button>
</div>
</div>
<div class="btn-toolbar col-md-7" role="toolbar" aria-label="Toolbar with button groups">
<div class="input-group">
<div class="input-group-prepend">
<div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">UI</div>
</div>
</div>
<div class="btn-group" role="group" aria-label="First group">
<button type="button" class="btn btn-default generator" id="swagger-ui">swagger-ui</button>
<button type="button" class="btn btn-default generator" id="element-ui">element-ui</button>
<button type="button" class="btn btn-default generator" id="bootstrap-ui">bootstrap-ui</button>
<button type="button" class="btn btn-default generator" id="layui-edit">layui-edit</button>
<button type="button" class="btn btn-default generator" id="layui-list">layui-list</button>
</div>
</div>
</div>
<div class="row" style="margin-top: 10px;">
<div class="btn-toolbar col-md-5" role="toolbar" aria-label="Toolbar with button groups">
<div class="input-group">
<div class="input-group-prepend">
<div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">BeetlSQL</div>
</div>
</div>
<div class="btn-group" role="group" aria-label="First group">
<button type="button" class="btn btn-default generator" id="beetlmd">beetlmd</button>
<button type="button" class="btn btn-default generator" id="beetlcontroller">beetlcontroller</button>
</div>
</div>
<div class="btn-toolbar col-md-5" role="toolbar" aria-label="Toolbar with button groups">
<div class="input-group">
<div class="input-group-prepend">
<div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">JPA</div>
</div>
</div>
<div class="btn-group" role="group" aria-label="First group">
<button type="button" class="btn btn-default generator" id="entity">jpa-entity</button>
<button type="button" class="btn btn-default generator" id="repository">repository</button>
<button type="button" class="btn btn-default generator" id="jpacontroller">controller</button>
</div>
</div>
</div>
<div class="row" style="margin-top: 10px;">
<div class="btn-toolbar col-md-5" role="toolbar" aria-label="Toolbar with button groups">
<div class="input-group">
<div class="input-group-prepend">
<div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">JdbcTemplate</div>
</div>
</div>
<div class="btn-group" role="group" aria-label="First group">
<button type="button" class="btn btn-default generator" id="jtdaoimpl">daoimpl</button>
<button type="button" class="btn btn-default generator" id="jtdao">dao</button>
</div>
</div>
<div class="btn-toolbar col-md-7" role="toolbar" aria-label="Toolbar with button groups">
<div class="input-group">
<div class="input-group-prepend">
<div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">SQL</div>
</div>
</div>
<div class="btn-group" role="group" aria-label="First group">
<button type="button" class="btn btn-default generator" id="select">select</button>
<button type="button" class="btn btn-default generator" id="insert">insert</button>
<button type="button" class="btn btn-default generator" id="update">update</button>
<button type="button" class="btn btn-default generator" id="delete">delete</button>
</div>
</div>
</div>
<div class="row" style="margin-top: 10px;">
<div class="btn-toolbar col-md-5" role="toolbar" aria-label="Toolbar with button groups">
<div class="input-group">
<div class="input-group-prepend">
<div class="btn btn-secondary disabled setWidth" id="btnGroupAddon">Util</div>
</div>
</div>
<div class="btn-group" role="group" aria-label="First group">
<button type="button" class="btn btn-default generator" id="util">bean get set</button>
<button type="button" class="btn btn-default generator" id="json">json</button>
<button type="button" class="btn btn-default generator" id="xml">xml</button>
</div>
</div>
</div>
<hr>
<textarea id="genCodeArea" class="form-control btn-lg" ></textarea>
</div>
</div>
<@netCommon.commonFooter />
</body>
</html>

44
pom.xml
View File

@@ -5,7 +5,7 @@
<groupId>com.softdev.system</groupId> <groupId>com.softdev.system</groupId>
<artifactId>SpringBootCodeGenerator</artifactId> <artifactId>SpringBootCodeGenerator</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>2.0</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<parent> <parent>
@@ -74,26 +74,11 @@
<version>1.2.8.RELEASE</version> <version>1.2.8.RELEASE</version>
</dependency>--> </dependency>-->
<!-- Hutool超级工具类 http://hutool.mydoc.io/ --> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.0.6</version>
</dependency>
<!-- lombok -->
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
<version>1.18.8</version> <version>1.18.12</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8</version>
</dependency> </dependency>
<!-- freemarker --> <!-- freemarker -->
@@ -102,28 +87,6 @@
<artifactId>spring-boot-starter-freemarker</artifactId> <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency> </dependency>
<!-- java.lang.ClassNotFoundException: javax.xml.bind.JAXBException/javax.xml.bind.annotation.XmlType问题解决 -->
<!--<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>-->
</dependencies> </dependencies>
@@ -186,7 +149,6 @@
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
<version>2.0.4.RELEASE</version>
<executions> <executions>
<execution> <execution>
<goals> <goals>