10 Commits

Author SHA1 Message Date
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
gaohang
9b6562b773 Merge pull request #7 from moshowgame/master
merge
2020-02-22 00:02:43 +08:00
25 changed files with 528 additions and 384 deletions

3
.gitignore vendored
View File

@@ -198,4 +198,7 @@ buildNumber.properties
.mvn/timing.properties
.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

View File

@@ -7,10 +7,16 @@
# Description
- √ 基于SpringBoot2+Freemarker+Bootstrap
- √ 以放双手为目的
- √ 以放双手为目的减少大量重复的CRUD工作
- √ 支持mysql/oracle/pgsql三大数据库
- √ 用DDL-SQL语句生成JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL相关代码.
# Advantage
- 自动记忆最近生成的内容最多保留9个
- 支持特殊字符模板(`#`请用`井`代替;`$`请用`¥`代替)
- 提供众多通用模板易于使用复制粘贴加简单修改即可完成CRUD操作
- 支持JSON逆向生成(只支持简单的一级树)
# Url
@@ -20,13 +26,14 @@
|CSDN博客|http://zhengkai.blog.csdn.net|
|最新Jar包|https://github.com/moshowgame/SpringBootCodeGenerator/releases|
感谢bejson三叔将他部署在[BEJSON](www.bejson.com)上目前是besjon专供工具(线上版本不一定是最新的,会有延迟,请谅解,谢谢).
感谢bejson三叔将他部署在[BEJSON](www.bejson.com)上目前是besjon专供的金牌工具(线上版本不一定是最新的,会有延迟,请谅解,谢谢).
# Update
|更新日期|更新内容|
|-|-|
|20200517|1.代码重构异常处理优化Freemarker相关工具类优化简化模板生成部分通过template.json来配置需要生成的模板不需要配置java文件。 2.修复包含comment关键字时注释无法识别的问题。(感谢@1nchaos的反馈) 3.赞赏优化,感谢大家的赞赏 4.新增mapper2(Mybatis-Annotation模板)(感谢@baisi525和@CHKEGit的建议)。|
|20200503|1.优化对特殊字符的处理,对于包含#和$等特殊字符的在模板使用井和¥代替便可escapeString方法会自动处理<br> 2.优化mybatisplus实体类相关(感谢@chunchengmeigui的反馈) 3.修优化对所有类型的判断(感谢@cnlw的反馈) 4.移除swagger-entity该功能已经包含在swagger-ui的下拉选项中 5.升级hutool和lombok版本|
|20200306|1.提交一套layuimini+mybatisplus的模板. 2.修复mybatisplus一些相关问题. |
|20200206|1.新增历史记录功能,自动保存最近生成的对象 2.新增swagger开关选项和修复@Column带name参数(感谢@liuyu-struggle的建议) 3.去除mybatis模板中的方括号[]和修改模板里的类注释样式(感谢@gaohanghang的PR)|
@@ -39,8 +46,7 @@
|20191115|1.添加tinyint类型转换(感谢@lixiliang&@liujiansgit的Suggestion) 2.添加一键复制功能(感谢@gaohanghang的Suggestion) 3.Mybatis的insert增加keyProperty="id"用于返回自增id(感谢@88888888888888888888的Suggestion) 4.优化date类型的支持(感谢@SteveLsf的反馈) 5.其他一些优化. |
|20191015|修复jdbcTemplates中insert语句第一个字段丢失的问题. |
|20190915|1.添加对象getset模板 2.添加sql模板 3.启动类添加日志输出,方便项目使用(感谢@gaohanghang 的pull request) |
|20190910-2|优化以及更新Maven依赖减少打包体积. |
|20190910-1|1.修复mapper接口load方法但是xml中方法不匹配问题 2.移除mapper中CRUD时的@param 注解会影响xml的解析(感谢@caojiantao的反馈).3.优化MyBatis的xml文件对Oracle的支持.(感谢@wylove1992的反馈) 4.新增对boolean的处理(感谢@violinxsc的反馈)以及优化tinyint类型生成boolean类型问题(感谢@hahaYhui的反馈) |
|20190910|优化以及更新Maven依赖减少打包体积. 1.修复mapper接口load方法但是xml中方法不匹配问题 2.移除mapper中CRUD时的@param 注解会影响xml的解析(感谢@caojiantao的反馈).3.优化MyBatis的xml文件对Oracle的支持.(感谢@wylove1992的反馈) 4.新增对boolean的处理(感谢@violinxsc的反馈)以及优化tinyint类型生成boolean类型问题(感谢@hahaYhui的反馈) |
|20190909|添加是否下划线转换为驼峰的选择(感谢@youngking28 的pull request).|
|20190518|1.优化注释 2.修改 mybatis模板中 controller注解 3.修改 mybatis模板中 dao文件使用为 mapper文件 4.修改 mybatis模板中 service实现类中的一个 bug 5.修改 index.ftl文件中 mybatis模板的 dao -> mapper(感谢@unqin的pull request)|
|20190511|优化mybatis模块的dao和xml模板修改dao接口注解为@Repository所有dao参数改为包装类删除update语句最后的UpdateTime = NOW()修改dao接口文件的方法注释使其更符合javaDoc的标准修改insert语句增加插入行主键的返回修改load的方法名为selectByPrimaryKey修改xml的update语句新增动态if判空修改xml的insert语句新增动态插入判空更符合mybatisGenerator标准(感谢@Archer-Wen的贡献 ).|
@@ -65,7 +71,7 @@
|20180913|修复字段没有描述以及类型为DATE型导致的问题.新增JPA的Controller模板.|
|20180831|初始化项目.新增JPA系列Entity+Repository模板.|
# FieldName
# ClassInfo/TableInfo
|字段名|说明|
|-|-|
|packageName|自定义的包名|
@@ -77,10 +83,16 @@
|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.jpg">
<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

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

View File

@@ -4,9 +4,12 @@ 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 动态获取tomcat启动端口控制台打印项目访问地址
* @Description 通过实现ApplicationListener接口动态获取tomcat启动端口和访问路径通过InetAddress类获取主机的ip地址最后控制台打印项目访问地址
* @Author Gao Hang Hang
* @Date 2019-12-27 14:37
**/
@@ -14,15 +17,20 @@ import org.springframework.stereotype.Component;
@Slf4j
public class ServerConfig implements ApplicationListener<WebServerInitializedEvent> {
private int serverPort;
private String serverPath;
@Override
public void onApplicationEvent(WebServerInitializedEvent event) {
this.serverPort = event.getWebServer().getPort();
//新增动态path by zhengkai
this.serverPath = event.getApplicationContext().getApplicationName();
log.info("项目启动启动成功!访问地址: http://localhost:{}{}", serverPort,serverPath);
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,90 +1,72 @@
package com.softdev.system.generator.controller;
import com.alibaba.fastjson.JSON;
import com.softdev.system.generator.entity.ClassInfo;
import com.softdev.system.generator.entity.ParamInfo;
import com.softdev.system.generator.entity.ReturnT;
import com.softdev.system.generator.service.GeneratorService;
import com.softdev.system.generator.util.CodeGenerateException;
import com.softdev.system.generator.util.TableParseUtil;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
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.Map;
/**
* spring boot code generator
* @author zhengk/moshow
*/
@Controller
@Slf4j
public class IndexController {
@Autowired
private GeneratorService generatorService;
@GetMapping("/")
public String index() {
return "index";
}
@PostMapping("/genCode")
@ResponseBody
public ReturnT<Map<String, String>> codeGenerate(@RequestBody ParamInfo paramInfo ) {
try {
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("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 params
//log.info(JSON.toJSONString(paramInfo));
log.info("generator table:"+(classInfo==null?"":classInfo.getTableName())
+",field size:"+((classInfo==null||classInfo.getFieldList()==null)?"":classInfo.getFieldList().size()));
// 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());
}
}
}
package com.softdev.system.generator.controller;
import com.softdev.system.generator.entity.ClassInfo;
import com.softdev.system.generator.entity.ParamInfo;
import com.softdev.system.generator.entity.ReturnT;
import com.softdev.system.generator.service.GeneratorService;
import com.softdev.system.generator.util.TableParseUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
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.util.HashMap;
import java.util.Map;
/**
* spring boot code generator
* @author zhengk/moshow
*/
@Controller
@Slf4j
public class IndexController {
@Autowired
private GeneratorService generatorService;
@GetMapping("/")
public String index() {
return "index";
}
@PostMapping("/genCode")
@ResponseBody
public ReturnT<Map<String, String>> codeGenerate(@RequestBody ParamInfo paramInfo ) throws Exception {
if (paramInfo.getTableSql().trim().length()<1) {
return new ReturnT<>(ReturnT.FAIL_CODE, "表结构信息不可为空");
}
//1.Parse Table Structure 表结构解析
ClassInfo classInfo = null;
switch (paramInfo.getDataType()){
//JSON模式parse field from json string
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;
}
//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 new ReturnT<>(result);
}
}

View File

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

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

View File

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

View File

@@ -1,66 +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();
}
/**
* 传入需要转义的字符串进行转义
* 20200503 zhengkai.blog.csdn.net
* */
public String escapeString(String originStr){
return originStr.replaceAll("","\\#").replaceAll("","\\$");
}
/**
* 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);
//处理为template并进行转义
String htmlText = escapeString(processTemplateIntoString(template, params));
return htmlText;
}
}

View File

@@ -5,6 +5,8 @@ import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
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;
@@ -18,8 +20,21 @@ import java.util.Map;
* @author xuxueli 2018-05-02 19:56:00
*/
@Slf4j
@Component
public class FreemarkerUtil {
@Autowired
private Configuration configuration;
/**
* 传入需要转义的字符串进行转义
* 20200503 zhengkai.blog.csdn.net
* */
public static String escapeString(String originStr){
return originStr.replaceAll("","\\#").replaceAll("","\\$");
}
/**
* freemarker config
*/
@@ -32,7 +47,7 @@ public class FreemarkerUtil {
}
try {
freemarkerConfig.setDirectoryForTemplateLoading(new File(templatePath, "templates/xxl-code-generator"));
freemarkerConfig.setDirectoryForTemplateLoading(new File(templatePath, "templates/code-generator"));
freemarkerConfig.setNumberFormat("#");
freemarkerConfig.setClassicCompatible(true);
freemarkerConfig.setDefaultEncoding("UTF-8");
@@ -73,7 +88,7 @@ public class FreemarkerUtil {
throws IOException, TemplateException {
Template template = freemarkerConfig.getTemplate(templateName);
String htmlText = processTemplateIntoString(template, params);
String htmlText = escapeString(processTemplateIntoString(template, params));
return htmlText;
}

View File

@@ -17,13 +17,13 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 表格解析Util
* @author zhengkai.blog.csdn.net
*/
public class TableParseUtil {
/**
* 解析建表SQL生成代码model-dao-xml
*
* 解析DDL SQL生成类信息
* @param paramInfo
* @return
*/
@@ -35,7 +35,7 @@ public class TableParseUtil {
String tinyintTransType=paramInfo.getTinyintTransType();
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
tableSql = tableSql.trim().replaceAll("'","`").replaceAll("\"","`").replaceAll("",",").toLowerCase();
@@ -48,7 +48,7 @@ public class TableParseUtil {
} else if (tableSql.contains("table") && tableSql.contains("(")) {
tableName = tableSql.substring(tableSql.indexOf("table")+5, tableSql.indexOf("("));
} else {
throw new CodeGenerateException("Table structure anomaly.");
throw new CodeGenerateException("Table structure incorrect.表结构不正确。");
}
//新增处理create table if not exists members情况
@@ -263,12 +263,13 @@ public class TableParseUtil {
fieldComment=columnName;
while(columnCommentMatcher.find()){
String columnCommentTmp = columnCommentMatcher.group();
System.out.println(columnCommentTmp);
//System.out.println(columnCommentTmp);
fieldComment = tableSql.substring(tableSql.indexOf(columnCommentTmp)+columnCommentTmp.length()).trim();
fieldComment = fieldComment.substring(0,fieldComment.indexOf("`")).trim();
}
}else if (columnLine.contains("comment")) {
String commentTmp = columnLine.substring(columnLine.indexOf("comment")+7).trim();
}else if (columnLine.contains(" comment")) {
//20200518 zhengkai 修复包含comment关键字的问题
String commentTmp = columnLine.substring(columnLine.lastIndexOf("comment")+7).trim();
// '用户ID',
if (commentTmp.contains("`") || commentTmp.indexOf("`")!=commentTmp.lastIndexOf("`")) {
commentTmp = commentTmp.substring(commentTmp.indexOf("`")+1, commentTmp.lastIndexOf("`"));
@@ -307,7 +308,7 @@ public class TableParseUtil {
return codeJavaInfo;
}
/**
* parse JSON
* 解析JSON生成类信息
* @param paramInfo
* @return
*/

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
-->
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_1.xsd">
<classpath>
<dir name="E:/workspace/idea with spring/SpringBootCodeGenerator/generator-web/target/classes">
</dir>
</classpath>
</application>

View File

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

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

@@ -12,8 +12,8 @@ import com.baomidou.mybatisplus.annotation.TableId;
* @author ${authorName}
* @date ${.now?string('yyyy-MM-dd HH:mm:ss')}
*/
@Data
<#if swagger?exists && swagger==true>@ApiModel("${classInfo.classComment}")</#if>
@Data<#if swagger?exists && swagger==true>
@ApiModel("${classInfo.classComment}")</#if>
public class ${classInfo.className} implements Serializable {
private static final long serialVersionUID = 1L;

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 HH:mm:ss')}
*/
@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

@@ -154,7 +154,7 @@
*/
function donate(){
if($("#donate").attr("show")=="no"){
$("#donate").html('<img src="http://upyun.bejson.com/img/zhengkai.png"></img>');
$("#donate").html('<img src="https://raw.githubusercontent.com/moshowgame/SpringBootCodeGenerator/master/donate.png"></img>');
$("#donate").attr("show","yes");
}else{
$("#donate").html('<p>谢谢赞赏!</p>');
@@ -206,7 +206,7 @@
<a class="navbar-brand" href="http://www.bejson.com">BeJSON在线工具站</a>
<ul class="nav navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="http://zhengkai.blog.csdn.net">大狼狗CSDN</a>
<a class="nav-link" href="http://zhengkai.blog.csdn.net">zhengkai.blog.csdn.net</a>
</li>
</ul>
</nav>
@@ -217,7 +217,9 @@
<div class="container">
<h2>Spring Boot Code Generator!</h2>
<p class="lead">
√基于SpringBoot2+Freemarker的<a class="lead" href="https://github.com/moshowgame/SpringBootCodeGenerator">代码生成器</a>√以释放双手为目的√支持mysql/oracle/pgsql三大数据库<br>
√基于SpringBoot2+Freemarker的<a class="lead" href="https://github.com/moshowgame/SpringBootCodeGenerator">代码生成器</a><br>
√以解放双手为目的减少大量重复的CRUD工作<br>
√支持mysql/oracle/pgsql三大数据库<br>
√用DDL-SQL语句生成JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL相关代码。<br>
如果发现有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>
</p>
@@ -279,7 +281,7 @@
<textarea id="ddlSqlArea" placeholder="请输入表结构信息..." class="form-control btn-lg" style="height: 250px;">
CREATE TABLE 'userinfo' (
'user_id' int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
'username' varchar(255) NOT NULL COMMENT '用户名',
'user_name' varchar(255) NOT NULL COMMENT '用户名',
'addtime' datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY ('user_id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户信息'
@@ -307,10 +309,11 @@ CREATE TABLE 'userinfo' (
</div>
</div>
<div class="btn-group" role="group" aria-label="First group">
<button type="button" class="btn btn-default generator" id="mybatis">mybatis</button>
<button type="button" class="btn btn-default generator" id="mybatis">ibatisXml</button>
<button type="button" class="btn btn-default generator" id="mapper">mapper</button>
<button type="button" class="btn btn-default generator" id="mapper2">mapper2</button>
<button type="button" class="btn btn-default generator" id="service">service</button>
<button type="button" class="btn btn-default generator" id="service_impl">service_impl</button>
<button type="button" class="btn btn-default generator" id="service_impl">serviceImpl</button>
<button type="button" class="btn btn-default generator" id="controller">controller</button>
</div>
</div>

38
pom.xml
View File

@@ -74,14 +74,6 @@
<version>1.2.8.RELEASE</version>
</dependency>-->
<!-- Hutool超级工具类 http://hutool.mydoc.io/ -->
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
@@ -89,41 +81,12 @@
<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>
<!-- freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</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>
@@ -186,7 +149,6 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.0.4.RELEASE</version>
<executions>
<execution>
<goals>