From 1a6e1a3ffb9b57c5d83e1528a7e108d91702765c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moshow=E9=83=91=E9=94=B4?= Date: Mon, 23 Dec 2024 16:06:36 +0800 Subject: [PATCH] =?UTF-8?q?|=202024.12.23=20|=20=E6=96=B0=E5=A2=9EInsertSQ?= =?UTF-8?q?L=E6=A8=A1=E5=BC=8F=EF=BC=8C=E9=87=87=E7=94=A8JSQLParser?= =?UTF-8?q?=E5=BC=95=E6=93=8E=E8=BF=9B=E8=A1=8C=E5=B0=81=E8=A3=85
?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=E5=B0=81=E8=A3=85
CDN?= =?UTF-8?q?=E6=81=A2=E5=A4=8D=E4=B8=BAstaticfile.org=E5=8A=A0=E9=80=9F(?= =?UTF-8?q?=E5=A6=82=E6=9E=9C=E6=9C=AC=E5=9C=B0=E5=8D=A1=E7=9A=84=E8=AF=9D?= =?UTF-8?q?=EF=BC=8C=E5=BB=BA=E8=AE=AE=E5=88=87=E6=8D=A2local=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F)=E3=80=82
?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 42 +- generator-web/pom.xml | 8 +- .../controller/GeneratorController.java | 42 +- .../system/generator/entity/ParamInfo.java | 6 +- .../generator/service/GeneratorService.java | 40 +- .../service/GeneratorServiceImpl.java | 541 +++++++++++++++++- ...{StringUtils.java => StringUtilsPlus.java} | 2 +- .../system/generator/util/TableParseUtil.java | 446 --------------- .../src/main/resources/application-bejson.yml | 12 +- .../src/main/resources/application-dev.yml | 6 +- .../src/main/resources/statics/js/main.js | 2 +- .../src/main/resources/statics/version.json | 1 - .../resources/templates/header-CDN-v2.html | 40 +- .../src/main/resources/templates/index.html | 6 +- .../src/main/resources/templates/main-v2.html | 1 + generator-web/src/test/java/FooTest.java | 27 - .../generator/util/StringUtilsPlusTest.java | 104 ++++ .../generator/util/StringUtilsTest.java | 81 --- pom.xml | 21 +- 19 files changed, 778 insertions(+), 650 deletions(-) rename generator-web/src/main/java/com/softdev/system/generator/util/{StringUtils.java => StringUtilsPlus.java} (99%) delete mode 100644 generator-web/src/main/resources/statics/version.json delete mode 100644 generator-web/src/test/java/FooTest.java create mode 100644 generator-web/src/test/java/com/softdev/system/generator/util/StringUtilsPlusTest.java delete mode 100644 generator-web/src/test/java/com/softdev/system/generator/util/StringUtilsTest.java diff --git a/README.md b/README.md index 2af33f5..d09e77c 100644 --- a/README.md +++ b/README.md @@ -10,30 +10,31 @@ >powered by `Moshow郑锴(大狼狗)` , [https://zhengkai.blog.csdn.net](https://zhengkai.blog.csdn.net) # Description ->Based on SpringBoot2+Freemarker
-> #基于`SpringBoot2`和`Freemarker`的代码生成平台 +>The `Spring Boot Code Generator` , Based on SpringBoot3 and Freemarker
+> #基于`SpringBoot3`和`Freemarker`的代码生成平台 > ->For reducing the repetitive CRUD work
-> #以解放双手为目的,减少大量的`重复CRUD工作` +>Release your hands from tedious and repetitive CRUD tasks.
+> #从繁琐重复的`CRUD工作`中释放你的双手 > ->Support mysql, oracle and pgsql
+>Support mysql+oracle+pgsql , the most popular databases standard SQL
> #支持`MySQL`、Oracle、PgSQL三大主流数据库 > ->Generate to many predefined popular templates by DDL-SQL/Insert-SQL/Simple JSON
-> 可通过`建表SQL语句`或`INSERT语句`或者`简单JSON`生成预设的`JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL/CommonMapper`相关模板代码. +>Generate various templates through table creation DDL statements, Insert SQL statements, Select SQL statements(*New), and simple JSON.
+> 通过建表DDL语句、插入SQL语句、选择SQL语句(*新)以及简单JSON生成各种模板`JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL/CommonMapper`. > ->Thanks for your using and feedback,I'm inspired by the 1500+PV (AVG) every day and github more than 1.9K stars
-> 感谢大家的使用和反馈,每天1500的PV和获得超过九百多的星星是我前进和继续做下去的动力。 +>Thank you all for your use and feedback. The daily PV visits of 1.5k in BeJSON and 2K Stars on GitHub are the greatest encouragement and motivation.
+> 感谢大家的使用与反馈,BeJSON上每天1.5K的PV访问量👀和 Github上2K的✨Stars是最大的鼓励与动力。 > ->Hope everyone can keep good balance on work and life , stay health and safety . I wish you success in your new position and get promoted step by step.
+>May everyone maintain a work-life balance, stay healthy and safe. Wishing you all success in your work and continuous advancements!.
> 愿大家可以维持生活和工作平衡,保持健康和安全,祝大家工作顺利,步步高升! ->Please submit your issue and template , or pull your good idea into the PR
-> 提交你的问题和生成模板,或者提交你的好主意到PR。 +> +>Welcome to submit your issue and useful templates , or put your good idea into PR
+> 欢迎提交你的问题和常用有用模板,或者提交你的好主意到PR。 # URL -- 感谢`卡卡`将他部署在[BEJSON](https://java.bejson.com/generator)上,目前是besjon专供的`金牌工具`(线上版本不一定是最新的,会有延迟,请谅解,谢谢).
+- 感谢`卡卡`将他部署在[BEJSON](https://java.bejson.com/generator)上,目前是BeJSON专供的`金牌工具`(线上版本不一定是最新的,会有延迟,请谅解,谢谢).
- 感谢`jully.top`部署的副本 [https://jully.top/generator/](https://jully.top/generator/)。
- 感谢`BootCDN`提供稳定、快速、免费的前端开源项目 CDN 加速服务 - Thanks for `JetBrains` providing us the `Licenses for Open Source Development` ,[Get free access to all JetBrains tools for developing your open source project!](https://www.jetbrains.com/community/opensource/#support) .
@@ -49,7 +50,7 @@ | GITHUB仓库 | https://github.com/moshowgame/SpringBootCodeGenerator | # Tips or Features -- 支持`DDL SQL`/`INSERT SQL`/`SIMPLE JSON`三种生成模式 +- 支持`DDL SQL`/`INSERT SQL`/`SIMPLE JSON`/`SELECT SQL`(*New)四种生成模式 - `自动记忆`最近生成的内容,最多保留9个 - 提供众多`通用模板`,易于使用,复制粘贴加简单修改即可完成CRUD操作 - 支持`特殊字符`模板(`#`请用`井`代替;`$`请用`¥`代替) @@ -72,11 +73,12 @@ # Update Logs | 更新日期 | 更新内容 | |:-----------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 2024.04.23 | 切换为更快更稳定的BootCDN进行加速。
前端NEWUI改版(基于AdminLTE+Bootstrap+Vue+ElementUI混合模式)。| -| 2024.04.22 | [Java CI with Maven](https://github.com/moshowgame/SpringBootCodeGenerator/actions/workflows/maven.yml) 更新
SpringBoot升级到3.2.5
FastJSON升级到FastJSON2.0.49| -| 2024.04.21 | 推出JDK11分支,支持JDK8/JDK11/JDK17等版本,兼容性较好但维护速度较慢,为了更好兼容旧机器和旧环境| -| 2024.04.20 | 修复CDN版本cdn.staticfile.org域名备份失败问题,已同步更新到cdn.staticfile.net(本地版本则不受影响)| -| 2024.01.26 | 修复大写下滑线列名转驼峰问题(感谢@Nisus-Liu的PR)| +| 2024.12.23 | 新增InsertSQL模式,采用JSQLParser引擎进行封装
优化代码封装
CDN恢复为staticfile.org加速(如果本地卡的话,建议切换local模式)。
| +| 2024.04.23 | 切换为更快更稳定的BootCDN进行加速。
前端NEWUI改版(基于AdminLTE+Bootstrap+Vue+ElementUI混合模式)。 | +| 2024.04.22 | [Java CI with Maven](https://github.com/moshowgame/SpringBootCodeGenerator/actions/workflows/maven.yml) 更新
SpringBoot升级到3.2.5
FastJSON升级到FastJSON2.0.49 | +| 2024.04.21 | 推出JDK11分支,支持JDK8/JDK11/JDK17等版本,兼容性较好但维护速度较慢,为了更好兼容旧机器和旧环境 | +| 2024.04.20 | 修复CDN版本cdn.staticfile.org域名备份失败问题,已同步更新到cdn.staticfile.net(本地版本则不受影响) | +| 2024.01.26 | 修复大写下滑线列名转驼峰问题(感谢@Nisus-Liu的PR) | | 2023.10.22 | 工具站CDN更新。 | | 2023.08.31 | (感谢@Nisus-Liu的PR)
fix 驼峰列名转命名风格错误问题
增强转下划线命名风格, 对原始风格不敏感. 支持各种命名风格的列名 to 下划线
增加 NonCaseString 大小写不敏感字符串包装类, 简化编码
几点代码小优化。 | | 2023.07.11 | 安全更新,正式支持SpringBoot3,javax升级到jakarta。 | @@ -181,6 +183,8 @@ - 当项目从2.7.x的springboot升级到3.0.x的时候,遇到一个问题“java: 程序包javax.servlet.http不存在” 问题: [java: 程序包javax.servlet.http不存在](https://zhengkai.blog.csdn.net/article/details/131362304) +- [CSDN【SpringBoot2启示录】专栏](https://blog.csdn.net/moshowgame/category_9274885.html) + 2024 NEWUI版本 2021 半Vue半JS版本 diff --git a/generator-web/pom.xml b/generator-web/pom.xml index be74e21..2dc3742 100644 --- a/generator-web/pom.xml +++ b/generator-web/pom.xml @@ -46,7 +46,13 @@ org.springframework.boot spring-boot-autoconfigure - + + org.projectlombok + lombok + 1.18.32 + provided + + diff --git a/generator-web/src/main/java/com/softdev/system/generator/controller/GeneratorController.java b/generator-web/src/main/java/com/softdev/system/generator/controller/GeneratorController.java index da760b8..43830ce 100644 --- a/generator-web/src/main/java/com/softdev/system/generator/controller/GeneratorController.java +++ b/generator-web/src/main/java/com/softdev/system/generator/controller/GeneratorController.java @@ -8,6 +8,8 @@ import com.softdev.system.generator.util.MapUtil; import com.softdev.system.generator.util.TableParseUtil; import com.softdev.system.generator.util.ValueUtil; import lombok.extern.slf4j.Slf4j; +import net.sf.jsqlparser.parser.CCJSqlParserUtil; +import net.sf.jsqlparser.statement.Statement; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @@ -56,26 +58,36 @@ public class GeneratorController { if (StringUtils.isEmpty(paramInfo.getTableSql())) { return ReturnT.error("表结构信息为空"); } - //1.Parse Table Structure 表结构解析 ClassInfo classInfo = null; String dataType = MapUtil.getString(paramInfo.getOptions(),"dataType"); - if ("sql".equals(dataType)||dataType==null) { - classInfo = TableParseUtil.processTableIntoClassInfo(paramInfo); - }else if ("json".equals(dataType)) { - //JSON模式:parse field from json string - classInfo = TableParseUtil.processJsonToClassInfo(paramInfo); - //INSERT SQL模式:parse field from insert sql - } else if ("insert-sql".equals(dataType)) { - classInfo = TableParseUtil.processInsertSqlToClassInfo(paramInfo); - //正则表达式模式(非完善版本):parse sql by regex - } else if ("sql-regex".equals(dataType)) { - classInfo = TableParseUtil.processTableToClassInfoByRegex(paramInfo); - //默认模式:default parse sql by java + switch (dataType) { + case "sql": + //默认模式:parse DDL table structure from sql + classInfo = generatorService.processTableIntoClassInfo(paramInfo); + break; + case "json": + //JSON模式:parse field from json string + classInfo = generatorService.processJsonToClassInfo(paramInfo); + break; + case "insert-sql": + //INSERT SQL模式:parse field from insert sql + classInfo = generatorService.processInsertSqlToClassInfo(paramInfo); + break; + case "sql-regex": + //正则表达式模式(非完善版本):parse sql by regex + classInfo = generatorService.processTableToClassInfoByRegex(paramInfo); + break; + case "select-sql": + //SelectSqlBySQLPraser模式:parse select sql by JSqlParser + classInfo = generatorService.generateSelectSqlBySQLPraser(paramInfo); + break; + default: + //默认模式:parse DDL table structure from sql + classInfo = generatorService.processTableIntoClassInfo(paramInfo); + break; } - //2.Set the params 设置表格参数 - paramInfo.getOptions().put("classInfo", classInfo); paramInfo.getOptions().put("tableName", classInfo == null ? System.currentTimeMillis() : classInfo.getTableName()); diff --git a/generator-web/src/main/java/com/softdev/system/generator/entity/ParamInfo.java b/generator-web/src/main/java/com/softdev/system/generator/entity/ParamInfo.java index 697e3da..0493631 100644 --- a/generator-web/src/main/java/com/softdev/system/generator/entity/ParamInfo.java +++ b/generator-web/src/main/java/com/softdev/system/generator/entity/ParamInfo.java @@ -17,9 +17,9 @@ public class ParamInfo { @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"; + public static final String CAMEL_CASE = "CamelCase"; + public static final String UNDER_SCORE_CASE = "UnderScoreCase"; + public static final String UPPER_UNDER_SCORE_CASE = "UpperUnderScoreCase"; } } diff --git a/generator-web/src/main/java/com/softdev/system/generator/service/GeneratorService.java b/generator-web/src/main/java/com/softdev/system/generator/service/GeneratorService.java index f69850f..b58e08d 100644 --- a/generator-web/src/main/java/com/softdev/system/generator/service/GeneratorService.java +++ b/generator-web/src/main/java/com/softdev/system/generator/service/GeneratorService.java @@ -1,5 +1,7 @@ package com.softdev.system.generator.service; +import com.softdev.system.generator.entity.ClassInfo; +import com.softdev.system.generator.entity.ParamInfo; import freemarker.template.TemplateException; import org.springframework.stereotype.Service; @@ -15,6 +17,40 @@ public interface GeneratorService { String getTemplateConfig() throws IOException; - public Map getResultByParams(Map params) throws IOException, TemplateException; - + Map getResultByParams(Map params) throws IOException, TemplateException; + /** + * 解析Select-SQL生成类信息(JSQLPraser版本) + * @auther: zhengkai.blog.csdn.net + * @param paramInfo + * @return + */ + ClassInfo generateSelectSqlBySQLPraser(ParamInfo paramInfo) throws Exception; + /** + * 解析DDL-SQL生成类信息 + * @auther: zhengkai.blog.csdn.net + * @param paramInfo + * @return + */ + ClassInfo processTableIntoClassInfo(ParamInfo paramInfo) throws Exception; + /** + * 解析JSON生成类信息 + * @auther: zhengkai.blog.csdn.net + * @param paramInfo + * @return + */ + ClassInfo processJsonToClassInfo(ParamInfo paramInfo); + /** + * 解析DDL SQL生成类信息-正则表达式版本 + * @auther: zhengkai.blog.csdn.net + * @param paramInfo + * @return + */ + ClassInfo processTableToClassInfoByRegex(ParamInfo paramInfo); + /** + * 解析INSERT-SQL生成类信息-正则表达式版本 + * @auther: zhengkai.blog.csdn.net + * @param paramInfo + * @return + */ + ClassInfo processInsertSqlToClassInfo(ParamInfo paramInfo); } diff --git a/generator-web/src/main/java/com/softdev/system/generator/service/GeneratorServiceImpl.java b/generator-web/src/main/java/com/softdev/system/generator/service/GeneratorServiceImpl.java index a480b81..54c30c3 100644 --- a/generator-web/src/main/java/com/softdev/system/generator/service/GeneratorServiceImpl.java +++ b/generator-web/src/main/java/com/softdev/system/generator/service/GeneratorServiceImpl.java @@ -3,22 +3,25 @@ package com.softdev.system.generator.service; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; -import com.softdev.system.generator.entity.TemplateConfig; -import com.softdev.system.generator.util.FreemarkerUtil; -import com.softdev.system.generator.util.MapUtil; +import com.softdev.system.generator.entity.*; +import com.softdev.system.generator.util.*; import freemarker.template.TemplateException; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; +import net.sf.jsqlparser.parser.CCJSqlParserUtil; +import net.sf.jsqlparser.schema.Column; +import net.sf.jsqlparser.statement.select.PlainSelect; +import net.sf.jsqlparser.statement.select.SelectItem; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -40,13 +43,10 @@ public class GeneratorServiceImpl implements GeneratorService { @Override 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(); - } + 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; } @@ -71,4 +71,515 @@ public class GeneratorServiceImpl implements GeneratorService { return result; } + /** + * 根据SQL解析器解析表结构 + * @author zhengkai.blog.csdn.net + * @param paramInfo + * @return + * @throws Exception + */ + @Override + public ClassInfo generateSelectSqlBySQLPraser(ParamInfo paramInfo) throws Exception { + ClassInfo classInfo = new ClassInfo(); + PlainSelect select = (PlainSelect) CCJSqlParserUtil.parse(paramInfo.getTableSql()); + List> columnNameList = select.getSelectItems(); + log.info("tableName:{}", select.getFromItem().toString()); + // field List + List fieldList = new ArrayList(); + columnNameList.forEach(t->{ + FieldInfo fieldInfo = new FieldInfo(); + String fieldName = ((Column)t.getExpression()).getColumnName(); + String aliasName = t.getAlias() != null ? t.getAlias().getName() : ((Column)t.getExpression()).getColumnName(); + //存储原始字段名 + fieldInfo.setFieldComment(aliasName);fieldInfo.setColumnName(aliasName); + //处理字段名是t.xxx的情况 + fieldName=fieldName.contains(".")?fieldName.substring(fieldName.indexOf(".")+1):fieldName; + //转换前 + fieldInfo.setColumnName(fieldName); + switch ((String) paramInfo.getOptions().get("nameCaseType")) { + case ParamInfo.NAME_CASE_TYPE.CAMEL_CASE: + // 2024-1-27 L&J 适配任意(maybe)原始风格转小写驼峰 + fieldName = StringUtilsPlus.toLowerCamel(aliasName); + break; + case ParamInfo.NAME_CASE_TYPE.UNDER_SCORE_CASE: + fieldName = StringUtilsPlus.toUnderline(aliasName, false); + break; + case ParamInfo.NAME_CASE_TYPE.UPPER_UNDER_SCORE_CASE: + fieldName = StringUtilsPlus.toUnderline(aliasName.toUpperCase(), true); + break; + default: + fieldName = aliasName; + break; + } + //转换后 + fieldInfo.setFieldName(fieldName); + + //无法推测类型,所有都set为String + fieldInfo.setFieldClass("String"); + fieldList.add(fieldInfo); + }); + classInfo.setFieldList(fieldList); + String tableName = select.getFromItem().toString(); + classInfo.setTableName(tableName); + //如果表名有空格,取空格前的第一个单词作为类名 + if(tableName.indexOf(" ")>0){ + classInfo.setClassName(StringUtilsPlus.upperCaseFirst(StringUtilsPlus.underlineToCamelCase(tableName.substring(0,tableName.indexOf(" "))))); + }else{ + classInfo.setClassName(StringUtilsPlus.upperCaseFirst(StringUtilsPlus.underlineToCamelCase(tableName))); + } + log.info("classInfo:{}", JSON.toJSONString(classInfo)); + return classInfo; + } + + /** + * 解析DDL SQL生成类信息(默认模式|核心模式) + * + * @param paramInfo + * @return + */ + @Override + public ClassInfo processTableIntoClassInfo(ParamInfo paramInfo) + throws IOException { + //process the param + NonCaseString tableSql = NonCaseString.of(paramInfo.getTableSql()); + String nameCaseType = MapUtil.getString(paramInfo.getOptions(),"nameCaseType"); + Boolean isPackageType = MapUtil.getBoolean(paramInfo.getOptions(),"isPackageType"); + + //更新空值处理 + if (StringUtils.isBlank(tableSql)) { + throw new CodeGenerateException("Table structure can not be empty. 表结构不能为空。"); + } + //deal with special character + tableSql = tableSql.trim() + .replaceAll("'", "`") + .replaceAll("\"", "`") + .replaceAll(",", ",") + // 这里全部转小写, 会让驼峰风格的字段名丢失驼峰信息(真有驼峰sql字段名的呢(* ̄︶ ̄)); 下文使用工具方法处理包含等 + // .toLowerCase() + ; + //deal with java string copy \n" + tableSql = tableSql.trim().replaceAll("\\\\n`", "").replaceAll("\\+", "").replaceAll("``", "`").replaceAll("\\\\", ""); + // table Name + String tableName = null; + int tableKwIx = tableSql.indexOf("TABLE"); // 包含判断和位置一次搞定 + if (tableKwIx > -1 && tableSql.contains("(")) { + tableName = tableSql.substring(tableKwIx + 5, tableSql.indexOf("(")).get(); + } else { + throw new CodeGenerateException("Table structure incorrect.表结构不正确。"); + } + + //新增处理create table if not exists members情况 + if (tableName.contains("if not exists")) { + tableName = tableName.replaceAll("if not exists", ""); + } + + if (tableName.contains("`")) { + tableName = tableName.substring(tableName.indexOf("`") + 1, tableName.lastIndexOf("`")); + } else { + //空格开头的,需要替换掉\n\t空格 + tableName = tableName.replaceAll(" ", "").replaceAll("\n", "").replaceAll("\t", ""); + } + //优化对byeas`.`ct_bd_customerdiscount这种命名的支持 + if (tableName.contains("`.`")) { + tableName = tableName.substring(tableName.indexOf("`.`") + 3); + } else if (tableName.contains(".")) { + //优化对likeu.members这种命名的支持 + tableName = tableName.substring(tableName.indexOf(".") + 1); + } + String originTableName = tableName; + //ignore prefix + if(tableName!=null && StringUtilsPlus.isNotNull(MapUtil.getString(paramInfo.getOptions(),"ignorePrefix"))){ + tableName = tableName.replaceAll(MapUtil.getString(paramInfo.getOptions(),"ignorePrefix"),""); + } + // class Name + String className = StringUtilsPlus.upperCaseFirst(StringUtilsPlus.underlineToCamelCase(tableName)); + if (className.contains("_")) { + className = className.replaceAll("_", ""); + } + + // class Comment + String classComment = null; + //mysql是comment=,pgsql/oracle是comment on table, + //2020-05-25 优化表备注的获取逻辑 + if (tableSql.containsAny("comment=", "comment on table")) { + int ix = tableSql.lastIndexOf("comment="); + String classCommentTmp = (ix > -1) ? + tableSql.substring(ix + 8).trim().get() : + tableSql.substring(tableSql.lastIndexOf("comment on table") + 17).trim().get(); + if (classCommentTmp.contains("`")) { + classCommentTmp = classCommentTmp.substring(classCommentTmp.indexOf("`") + 1); + classCommentTmp = classCommentTmp.substring(0, classCommentTmp.indexOf("`")); + classComment = classCommentTmp; + } else { + //非常规的没法分析 + classComment = className; + } + } else { + //修复表备注为空问题 + classComment = tableName; + } + //如果备注跟;混在一起,需要替换掉 + classComment = classComment.replaceAll(";", ""); + // field List + List fieldList = new ArrayList(); + + // 正常( ) 内的一定是字段相关的定义。 + String fieldListTmp = tableSql.substring(tableSql.indexOf("(") + 1, tableSql.lastIndexOf(")")).get(); + + // 匹配 comment,替换备注里的小逗号, 防止不小心被当成切割符号切割 + String commentPattenStr1 = "comment `(.*?)\\`"; + Matcher matcher1 = Pattern.compile(commentPattenStr1).matcher(fieldListTmp); + while (matcher1.find()) { + + String commentTmp = matcher1.group(); + //2018-9-27 zhengk 不替换,只处理,支持COMMENT评论里面多种注释 + //commentTmp = commentTmp.replaceAll("\\ comment `|\\`", " "); // "\\{|\\}" + + if (commentTmp.contains(",")) { + String commentTmpFinal = commentTmp.replaceAll(",", ","); + fieldListTmp = fieldListTmp.replace(matcher1.group(), commentTmpFinal); + } + } + //2018-10-18 zhengkai 新增支持double(10, 2)等类型中有英文逗号的特殊情况 + String commentPattenStr2 = "\\`(.*?)\\`"; + Matcher matcher2 = Pattern.compile(commentPattenStr2).matcher(fieldListTmp); + while (matcher2.find()) { + String commentTmp2 = matcher2.group(); + if (commentTmp2.contains(",")) { + String commentTmpFinal = commentTmp2.replaceAll(",", ",").replaceAll("\\(", "(").replaceAll("\\)", ")"); + fieldListTmp = fieldListTmp.replace(matcher2.group(), commentTmpFinal); + } + } + //2018-10-18 zhengkai 新增支持double(10, 2)等类型中有英文逗号的特殊情况 + String commentPattenStr3 = "\\((.*?)\\)"; + Matcher matcher3 = Pattern.compile(commentPattenStr3).matcher(fieldListTmp); + while (matcher3.find()) { + String commentTmp3 = matcher3.group(); + if (commentTmp3.contains(",")) { + String commentTmpFinal = commentTmp3.replaceAll(",", ","); + fieldListTmp = fieldListTmp.replace(matcher3.group(), commentTmpFinal); + } + } + String[] fieldLineList = fieldListTmp.split(","); + if (fieldLineList.length > 0) { + int i = 0; + //i为了解决primary key关键字出现的地方,出现在前3行,一般和id有关 + for (String columnLine0 : fieldLineList) { + NonCaseString columnLine = NonCaseString.of(columnLine0); + i++; + columnLine = columnLine.replaceAll("\n", "").replaceAll("\t", "").trim(); + // `userid` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID', + // 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 要在条件中使用复杂的表达式 + // 2019-4-29 zhengkai 优化对普通和特殊storage关键字的判断(感谢@AhHeadFloating的反馈 ) + // 2020-10-20 zhengkai 优化对fulltext/index关键字的处理(感谢@WEGFan的反馈) + // 2023-8-27 L&J 改用工具方法判断, 且修改变量名(非特殊标识), 方法抽取 + boolean notSpecialFlag = isNotSpecialColumnLine(columnLine, i); + + if (notSpecialFlag) { + //如果是oracle的number(x,x),可能出现最后分割残留的,x),这里做排除处理 + if (columnLine.length() < 5) { + continue; + } + //2018-9-16 zhengkai 支持'符号以及空格的oracle语句// userid` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID', + String columnName = ""; + columnLine = columnLine.replaceAll("`", " ").replaceAll("\"", " ").replaceAll("'", "").replaceAll(" ", " ").trim(); + //如果遇到username varchar(65) default '' not null,这种情况,判断第一个空格是否比第一个引号前 + try { + columnName = columnLine.substring(0, columnLine.indexOf(" ")).get(); + } catch (StringIndexOutOfBoundsException e) { + System.out.println("err happened: " + columnLine); + throw e; + } + + // field Name + // 2019-09-08 yj 添加是否下划线转换为驼峰的判断 + // 2023-8-27 L&J 支持原始列名任意命名风格, 不依赖用户是否输入下划线 + String fieldName = null; + if (ParamInfo.NAME_CASE_TYPE.CAMEL_CASE.equals(nameCaseType)) { + // 2024-1-27 L&J 适配任意(maybe)原始风格转小写驼峰 + fieldName = StringUtilsPlus.toLowerCamel(columnName); + } else if (ParamInfo.NAME_CASE_TYPE.UNDER_SCORE_CASE.equals(nameCaseType)) { + fieldName = StringUtilsPlus.toUnderline(columnName, false); + } else if (ParamInfo.NAME_CASE_TYPE.UPPER_UNDER_SCORE_CASE.equals(nameCaseType)) { + fieldName = StringUtilsPlus.toUnderline(columnName.toUpperCase(), true); + } else { + fieldName = columnName; + } + columnLine = columnLine.substring(columnLine.indexOf("`") + 1).trim(); + String mysqlType = columnLine.split("\\s+")[1]; + if(mysqlType.contains("(")){ + mysqlType = mysqlType.substring(0, mysqlType.indexOf("(")); + } + //swagger class + String swaggerClass = "string" ; + if(mysqlJavaTypeUtil.getMysqlSwaggerTypeMap().containsKey(mysqlType)){ + swaggerClass = mysqlJavaTypeUtil.getMysqlSwaggerTypeMap().get(mysqlType); + } + // field class + // int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID', + String fieldClass = "String"; + //2018-9-16 zhengk 补充char/clob/blob/json等类型,如果类型未知,默认为String + //2018-11-22 lshz0088 处理字段类型的时候,不严谨columnLine.contains(" int") 类似这种的,可在前后适当加一些空格之类的加以区分,否则当我的字段包含这些字符的时候,产生类型判断问题。 + //2020-05-03 MOSHOW.K.ZHENG 优化对所有类型的处理 + //2020-10-20 zhengkai 新增包装类型的转换选择 + if(mysqlJavaTypeUtil.getMysqlJavaTypeMap().containsKey(mysqlType)){ + fieldClass = mysqlJavaTypeUtil.getMysqlJavaTypeMap().get(mysqlType); + } + // field comment,MySQL的一般位于field行,而pgsql和oralce多位于后面。 + String fieldComment = null; + if (tableSql.contains("comment on column") && (tableSql.contains("." + columnName + " is ") || tableSql.contains(".`" + columnName + "` is"))) { + //新增对pgsql/oracle的字段备注支持 + //COMMENT ON COLUMN public.check_info.check_name IS '检查者名称'; + //2018-11-22 lshz0088 正则表达式的点号前面应该加上两个反斜杠,否则会认为是任意字符 + //2019-4-29 zhengkai 优化对oracle注释comment on column的支持(@liukex) + tableSql = tableSql.replaceAll(".`" + columnName + "` is", "." + columnName + " is"); + Matcher columnCommentMatcher = Pattern.compile("\\." + columnName + " is `").matcher(tableSql); + fieldComment = columnName; + while (columnCommentMatcher.find()) { + String columnCommentTmp = columnCommentMatcher.group(); + //System.out.println(columnCommentTmp); + fieldComment = tableSql.substring(tableSql.indexOf(columnCommentTmp) + columnCommentTmp.length()).trim().get(); + fieldComment = fieldComment.substring(0, fieldComment.indexOf("`")).trim(); + } + } else if (columnLine.contains(" comment")) { + //20200518 zhengkai 修复包含comment关键字的问题 + String commentTmp = columnLine.substring(columnLine.lastIndexOf("comment") + 7).trim().get(); + // '用户ID', + if (commentTmp.contains("`") || commentTmp.indexOf("`") != commentTmp.lastIndexOf("`")) { + commentTmp = commentTmp.substring(commentTmp.indexOf("`") + 1, commentTmp.lastIndexOf("`")); + } + //解决最后一句是评论,无主键且连着)的问题:album_id int(3) default '1' null comment '相册id:0 代表头像 1代表照片墙') + if (commentTmp.contains(")")) { + commentTmp = commentTmp.substring(0, commentTmp.lastIndexOf(")") + 1); + } + fieldComment = commentTmp; + } else { + //修复comment不存在导致报错的问题 + fieldComment = columnName; + } + + FieldInfo fieldInfo = new FieldInfo(); + // + fieldInfo.setColumnName(columnName); + fieldInfo.setFieldName(fieldName); + fieldInfo.setFieldClass(fieldClass); + fieldInfo.setSwaggerClass(swaggerClass); + fieldInfo.setFieldComment(fieldComment); + + fieldList.add(fieldInfo); + } + } + } + + if (fieldList.size() < 1) { + throw new CodeGenerateException("表结构分析失败,请检查语句或者提交issue给我"); + } + + ClassInfo codeJavaInfo = new ClassInfo(); + codeJavaInfo.setTableName(tableName); + codeJavaInfo.setClassName(className); + codeJavaInfo.setClassComment(classComment); + codeJavaInfo.setFieldList(fieldList); + codeJavaInfo.setOriginTableName(originTableName); + + return codeJavaInfo; + } + + private static boolean isNotSpecialColumnLine(NonCaseString columnLine, int lineSeq) { + return ( + !columnLine.containsAny( + "key ", + "constraint", + " using ", + "unique ", + "fulltext ", + "index ", + "pctincrease", + "buffer_pool", + "tablespace" + ) + && !(columnLine.contains("primary ") && columnLine.indexOf("storage") + 3 > columnLine.indexOf("(")) + && !(columnLine.contains("primary ") && lineSeq > 3) + ); + } + + /** + * 解析JSON生成类信息 + * + * @param paramInfo + * @return + */ + @Override + public ClassInfo processJsonToClassInfo(ParamInfo paramInfo) { + ClassInfo codeJavaInfo = new ClassInfo(); + codeJavaInfo.setTableName("JsonDto"); + codeJavaInfo.setClassName("JsonDto"); + codeJavaInfo.setClassComment("JsonDto"); + + //support children json if forget to add '{' in front of json + if (paramInfo.getTableSql().trim().startsWith("\"")) { + paramInfo.setTableSql("{" + paramInfo.getTableSql()); + } + if (JSON.isValid(paramInfo.getTableSql())) { + if (paramInfo.getTableSql().trim().startsWith("{")) { + JSONObject jsonObject = JSONObject.parseObject(paramInfo.getTableSql().trim()); + //parse FieldList by JSONObject + codeJavaInfo.setFieldList(processJsonObjectToFieldList(jsonObject)); + } else if (paramInfo.getTableSql().trim().startsWith("[")) { + JSONArray jsonArray = JSONArray.parseArray(paramInfo.getTableSql().trim()); + //parse FieldList by JSONObject + codeJavaInfo.setFieldList(processJsonObjectToFieldList(jsonArray.getJSONObject(0))); + } + } + + return codeJavaInfo; + } + + /** + * parse SQL by regex + * + * @param paramInfo + * @return + * @author https://github.com/ydq + */ + public ClassInfo processTableToClassInfoByRegex(ParamInfo paramInfo) { + // field List + List fieldList = new ArrayList(); + //return classInfo + ClassInfo codeJavaInfo = new ClassInfo(); + + //匹配整个ddl,将ddl分为表名,列sql部分,表注释 + String DDL_PATTEN_STR = "\\s*create\\s+table\\s+(?\\S+)[^\\(]*\\((?[\\s\\S]+)\\)[^\\)]+?(comment\\s*(=|on\\s+table)\\s*'(?.*?)'\\s*;?)?$"; + + Pattern DDL_PATTERN = Pattern.compile(DDL_PATTEN_STR, Pattern.CASE_INSENSITIVE); + + //匹配列sql部分,分别解析每一列的列名 类型 和列注释 + String COL_PATTERN_STR = "\\s*(?\\S+)\\s+(?\\w+)\\s*(?:\\([\\s\\d,]+\\))?((?!comment).)*(comment\\s*'(?.*?)')?\\s*(,|$)"; + + Pattern COL_PATTERN = Pattern.compile(COL_PATTERN_STR, Pattern.CASE_INSENSITIVE); + + Matcher matcher = DDL_PATTERN.matcher(paramInfo.getTableSql().trim()); + if (matcher.find()) { + String tableName = matcher.group("tableName"); + String tableComment = matcher.group("tableComment"); + codeJavaInfo.setTableName(tableName.replaceAll("'", "")); + codeJavaInfo.setClassName(tableName.replaceAll("'", "")); + codeJavaInfo.setClassComment(tableComment.replaceAll("'", "")); + String columnsSQL = matcher.group("columnsSQL"); + if (columnsSQL != null && columnsSQL.length() > 0) { + Matcher colMatcher = COL_PATTERN.matcher(columnsSQL); + while (colMatcher.find()) { + String fieldName = colMatcher.group("fieldName"); + String fieldType = colMatcher.group("fieldType"); + String fieldComment = colMatcher.group("fieldComment"); + if (!"key".equalsIgnoreCase(fieldType)) { + FieldInfo fieldInfo = new FieldInfo(); + fieldInfo.setFieldName(fieldName.replaceAll("'", "")); + fieldInfo.setColumnName(fieldName.replaceAll("'", "")); + fieldInfo.setFieldClass(fieldType.replaceAll("'", "")); + fieldInfo.setFieldComment(fieldComment.replaceAll("'", "")); + fieldList.add(fieldInfo); + } + } + } + codeJavaInfo.setFieldList(fieldList); + } + return codeJavaInfo; + } + + public List processJsonObjectToFieldList(JSONObject jsonObject) { + // field List + List fieldList = new ArrayList(); + jsonObject.keySet().stream().forEach(jsonField -> { + FieldInfo fieldInfo = new FieldInfo(); + fieldInfo.setFieldName(jsonField); + fieldInfo.setColumnName(jsonField); + fieldInfo.setFieldClass(String.class.getSimpleName()); + fieldInfo.setFieldComment("father:" + jsonField); + fieldList.add(fieldInfo); + if (jsonObject.get(jsonField) instanceof JSONArray) { + jsonObject.getJSONArray(jsonField).stream().forEach(arrayObject -> { + FieldInfo fieldInfo2 = new FieldInfo(); + fieldInfo2.setFieldName(arrayObject.toString()); + fieldInfo2.setColumnName(arrayObject.toString()); + fieldInfo2.setFieldClass(String.class.getSimpleName()); + fieldInfo2.setFieldComment("children:" + arrayObject.toString()); + fieldList.add(fieldInfo2); + }); + } else if (jsonObject.get(jsonField) instanceof JSONObject) { + jsonObject.getJSONObject(jsonField).keySet().stream().forEach(arrayObject -> { + FieldInfo fieldInfo2 = new FieldInfo(); + fieldInfo2.setFieldName(arrayObject.toString()); + fieldInfo2.setColumnName(arrayObject.toString()); + fieldInfo2.setFieldClass(String.class.getSimpleName()); + fieldInfo2.setFieldComment("children:" + arrayObject.toString()); + fieldList.add(fieldInfo2); + }); + } + }); + if (fieldList.size() < 1) { + throw new CodeGenerateException("JSON解析失败"); + } + return fieldList; + } + + public ClassInfo processInsertSqlToClassInfo(ParamInfo paramInfo) { + // field List + List fieldList = new ArrayList(); + //return classInfo + ClassInfo codeJavaInfo = new ClassInfo(); + + //get origin sql + String fieldSqlStr = paramInfo.getTableSql().toLowerCase().trim(); + fieldSqlStr = fieldSqlStr.replaceAll(" ", " ").replaceAll("\\\\n`", "") + .replaceAll("\\+", "").replaceAll("``", "`").replaceAll("\\\\", ""); + String valueStr = fieldSqlStr.substring(fieldSqlStr.lastIndexOf("values") + 6).replaceAll(" ", "").replaceAll("\\(", "").replaceAll("\\)", ""); + //get the string between insert into and values + fieldSqlStr = fieldSqlStr.substring(0, fieldSqlStr.lastIndexOf("values")); + + System.out.println(fieldSqlStr); + + String insertSqlPattenStr = "insert into (?.*) \\((?.*)\\)"; + //String DDL_PATTEN_STR="\\s*create\\s+table\\s+(?\\S+)[^\\(]*\\((?[\\s\\S]+)\\)[^\\)]+?(comment\\s*(=|on\\s+table)\\s*'(?.*?)'\\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 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; + } + } diff --git a/generator-web/src/main/java/com/softdev/system/generator/util/StringUtils.java b/generator-web/src/main/java/com/softdev/system/generator/util/StringUtilsPlus.java similarity index 99% rename from generator-web/src/main/java/com/softdev/system/generator/util/StringUtils.java rename to generator-web/src/main/java/com/softdev/system/generator/util/StringUtilsPlus.java index 4274c88..2cc4ea5 100644 --- a/generator-web/src/main/java/com/softdev/system/generator/util/StringUtils.java +++ b/generator-web/src/main/java/com/softdev/system/generator/util/StringUtilsPlus.java @@ -5,7 +5,7 @@ package com.softdev.system.generator.util; * * @author xuxueli 2018-05-02 20:43:25 */ -public class StringUtils { +public class StringUtilsPlus { /** * 首字母大写 diff --git a/generator-web/src/main/java/com/softdev/system/generator/util/TableParseUtil.java b/generator-web/src/main/java/com/softdev/system/generator/util/TableParseUtil.java index 8bea6c2..340bab6 100644 --- a/generator-web/src/main/java/com/softdev/system/generator/util/TableParseUtil.java +++ b/generator-web/src/main/java/com/softdev/system/generator/util/TableParseUtil.java @@ -23,452 +23,6 @@ import java.util.regex.Pattern; */ public class TableParseUtil { - /** - * 解析DDL SQL生成类信息 - * - * @param paramInfo - * @return - */ - public static ClassInfo processTableIntoClassInfo(ParamInfo paramInfo) - throws IOException { - //process the param - NonCaseString tableSql = NonCaseString.of(paramInfo.getTableSql()); - String nameCaseType = MapUtil.getString(paramInfo.getOptions(),"nameCaseType"); - Boolean isPackageType = MapUtil.getBoolean(paramInfo.getOptions(),"isPackageType"); - if (tableSql == null || tableSql.trim().length() == 0) { - throw new CodeGenerateException("Table structure can not be empty. 表结构不能为空。"); - } - //deal with special character - tableSql = tableSql.trim() - .replaceAll("'", "`") - .replaceAll("\"", "`") - .replaceAll(",", ",") - // 这里全部转小写, 会让驼峰风格的字段名丢失驼峰信息(真有驼峰sql字段名的呢(* ̄︶ ̄)); 下文使用工具方法处理包含等 - // .toLowerCase() - ; - //deal with java string copy \n" - tableSql = tableSql.trim().replaceAll("\\\\n`", "").replaceAll("\\+", "").replaceAll("``", "`").replaceAll("\\\\", ""); - // table Name - String tableName = null; - int tableKwIx = tableSql.indexOf("TABLE"); // 包含判断和位置一次搞定 - if (tableKwIx > -1 && tableSql.contains("(")) { - tableName = tableSql.substring(tableKwIx + 5, tableSql.indexOf("(")).get(); - } else { - throw new CodeGenerateException("Table structure incorrect.表结构不正确。"); - } - - //新增处理create table if not exists members情况 - if (tableName.contains("if not exists")) { - tableName = tableName.replaceAll("if not exists", ""); - } - - if (tableName.contains("`")) { - tableName = tableName.substring(tableName.indexOf("`") + 1, tableName.lastIndexOf("`")); - } else { - //空格开头的,需要替换掉\n\t空格 - tableName = tableName.replaceAll(" ", "").replaceAll("\n", "").replaceAll("\t", ""); - } - //优化对byeas`.`ct_bd_customerdiscount这种命名的支持 - if (tableName.contains("`.`")) { - tableName = tableName.substring(tableName.indexOf("`.`") + 3); - } else if (tableName.contains(".")) { - //优化对likeu.members这种命名的支持 - tableName = tableName.substring(tableName.indexOf(".") + 1); - } - String originTableName = tableName; - //ignore prefix - if(tableName!=null && StringUtils.isNotNull(MapUtil.getString(paramInfo.getOptions(),"ignorePrefix"))){ - tableName = tableName.replaceAll(MapUtil.getString(paramInfo.getOptions(),"ignorePrefix"),""); - } - // class Name - String className = StringUtils.upperCaseFirst(StringUtils.underlineToCamelCase(tableName)); - if (className.contains("_")) { - className = className.replaceAll("_", ""); - } - - // class Comment - String classComment = null; - //mysql是comment=,pgsql/oracle是comment on table, - //2020-05-25 优化表备注的获取逻辑 - if (tableSql.containsAny("comment=", "comment on table")) { - int ix = tableSql.lastIndexOf("comment="); - String classCommentTmp = (ix > -1) ? - tableSql.substring(ix + 8).trim().get() : - tableSql.substring(tableSql.lastIndexOf("comment on table") + 17).trim().get(); - if (classCommentTmp.contains("`")) { - classCommentTmp = classCommentTmp.substring(classCommentTmp.indexOf("`") + 1); - classCommentTmp = classCommentTmp.substring(0, classCommentTmp.indexOf("`")); - classComment = classCommentTmp; - } else { - //非常规的没法分析 - classComment = className; - } - } else { - //修复表备注为空问题 - classComment = tableName; - } - //如果备注跟;混在一起,需要替换掉 - classComment = classComment.replaceAll(";", ""); - // field List - List fieldList = new ArrayList(); - - // 正常( ) 内的一定是字段相关的定义。 - String fieldListTmp = tableSql.substring(tableSql.indexOf("(") + 1, tableSql.lastIndexOf(")")).get(); - - // 匹配 comment,替换备注里的小逗号, 防止不小心被当成切割符号切割 - String commentPattenStr1 = "comment `(.*?)\\`"; - Matcher matcher1 = Pattern.compile(commentPattenStr1).matcher(fieldListTmp); - while (matcher1.find()) { - - String commentTmp = matcher1.group(); - //2018-9-27 zhengk 不替换,只处理,支持COMMENT评论里面多种注释 - //commentTmp = commentTmp.replaceAll("\\ comment `|\\`", " "); // "\\{|\\}" - - if (commentTmp.contains(",")) { - String commentTmpFinal = commentTmp.replaceAll(",", ","); - fieldListTmp = fieldListTmp.replace(matcher1.group(), commentTmpFinal); - } - } - //2018-10-18 zhengkai 新增支持double(10, 2)等类型中有英文逗号的特殊情况 - String commentPattenStr2 = "\\`(.*?)\\`"; - Matcher matcher2 = Pattern.compile(commentPattenStr2).matcher(fieldListTmp); - while (matcher2.find()) { - String commentTmp2 = matcher2.group(); - if (commentTmp2.contains(",")) { - String commentTmpFinal = commentTmp2.replaceAll(",", ",").replaceAll("\\(", "(").replaceAll("\\)", ")"); - fieldListTmp = fieldListTmp.replace(matcher2.group(), commentTmpFinal); - } - } - //2018-10-18 zhengkai 新增支持double(10, 2)等类型中有英文逗号的特殊情况 - String commentPattenStr3 = "\\((.*?)\\)"; - Matcher matcher3 = Pattern.compile(commentPattenStr3).matcher(fieldListTmp); - while (matcher3.find()) { - String commentTmp3 = matcher3.group(); - if (commentTmp3.contains(",")) { - String commentTmpFinal = commentTmp3.replaceAll(",", ","); - fieldListTmp = fieldListTmp.replace(matcher3.group(), commentTmpFinal); - } - } - String[] fieldLineList = fieldListTmp.split(","); - if (fieldLineList.length > 0) { - int i = 0; - //i为了解决primary key关键字出现的地方,出现在前3行,一般和id有关 - for (String columnLine0 : fieldLineList) { - NonCaseString columnLine = NonCaseString.of(columnLine0); - i++; - columnLine = columnLine.replaceAll("\n", "").replaceAll("\t", "").trim(); - // `userid` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID', - // 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 要在条件中使用复杂的表达式 - // 2019-4-29 zhengkai 优化对普通和特殊storage关键字的判断(感谢@AhHeadFloating的反馈 ) - // 2020-10-20 zhengkai 优化对fulltext/index关键字的处理(感谢@WEGFan的反馈) - // 2023-8-27 L&J 改用工具方法判断, 且修改变量名(非特殊标识), 方法抽取 - boolean notSpecialFlag = isNotSpecialColumnLine(columnLine, i); - - if (notSpecialFlag) { - //如果是oracle的number(x,x),可能出现最后分割残留的,x),这里做排除处理 - if (columnLine.length() < 5) { - continue; - } - //2018-9-16 zhengkai 支持'符号以及空格的oracle语句// userid` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID', - String columnName = ""; - columnLine = columnLine.replaceAll("`", " ").replaceAll("\"", " ").replaceAll("'", "").replaceAll(" ", " ").trim(); - //如果遇到username varchar(65) default '' not null,这种情况,判断第一个空格是否比第一个引号前 - try { - columnName = columnLine.substring(0, columnLine.indexOf(" ")).get(); - } catch (StringIndexOutOfBoundsException e) { - System.out.println("err happened: " + columnLine); - throw e; - } - - // field Name - // 2019-09-08 yj 添加是否下划线转换为驼峰的判断 - // 2023-8-27 L&J 支持原始列名任意命名风格, 不依赖用户是否输入下划线 - String fieldName = null; - if (ParamInfo.NAME_CASE_TYPE.CAMEL_CASE.equals(nameCaseType)) { - // 2024-1-27 L&J 适配任意(maybe)原始风格转小写驼峰 - fieldName = StringUtils.toLowerCamel(columnName); - } else if (ParamInfo.NAME_CASE_TYPE.UNDER_SCORE_CASE.equals(nameCaseType)) { - fieldName = StringUtils.toUnderline(columnName, false); - } else if (ParamInfo.NAME_CASE_TYPE.UPPER_UNDER_SCORE_CASE.equals(nameCaseType)) { - fieldName = StringUtils.toUnderline(columnName.toUpperCase(), true); - } else { - fieldName = columnName; - } - columnLine = columnLine.substring(columnLine.indexOf("`") + 1).trim(); - String mysqlType = columnLine.split("\\s+")[1]; - if(mysqlType.contains("(")){ - mysqlType = mysqlType.substring(0, mysqlType.indexOf("(")); - } - //swagger class - String swaggerClass = "string" ; - if(mysqlJavaTypeUtil.getMysqlSwaggerTypeMap().containsKey(mysqlType)){ - swaggerClass = mysqlJavaTypeUtil.getMysqlSwaggerTypeMap().get(mysqlType); - } - // field class - // int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID', - String fieldClass = "String"; - //2018-9-16 zhengk 补充char/clob/blob/json等类型,如果类型未知,默认为String - //2018-11-22 lshz0088 处理字段类型的时候,不严谨columnLine.contains(" int") 类似这种的,可在前后适当加一些空格之类的加以区分,否则当我的字段包含这些字符的时候,产生类型判断问题。 - //2020-05-03 MOSHOW.K.ZHENG 优化对所有类型的处理 - //2020-10-20 zhengkai 新增包装类型的转换选择 - if(mysqlJavaTypeUtil.getMysqlJavaTypeMap().containsKey(mysqlType)){ - fieldClass = mysqlJavaTypeUtil.getMysqlJavaTypeMap().get(mysqlType); - } - // field comment,MySQL的一般位于field行,而pgsql和oralce多位于后面。 - String fieldComment = null; - if (tableSql.contains("comment on column") && (tableSql.contains("." + columnName + " is ") || tableSql.contains(".`" + columnName + "` is"))) { - //新增对pgsql/oracle的字段备注支持 - //COMMENT ON COLUMN public.check_info.check_name IS '检查者名称'; - //2018-11-22 lshz0088 正则表达式的点号前面应该加上两个反斜杠,否则会认为是任意字符 - //2019-4-29 zhengkai 优化对oracle注释comment on column的支持(@liukex) - tableSql = tableSql.replaceAll(".`" + columnName + "` is", "." + columnName + " is"); - Matcher columnCommentMatcher = Pattern.compile("\\." + columnName + " is `").matcher(tableSql); - fieldComment = columnName; - while (columnCommentMatcher.find()) { - String columnCommentTmp = columnCommentMatcher.group(); - //System.out.println(columnCommentTmp); - fieldComment = tableSql.substring(tableSql.indexOf(columnCommentTmp) + columnCommentTmp.length()).trim().get(); - fieldComment = fieldComment.substring(0, fieldComment.indexOf("`")).trim(); - } - } else if (columnLine.contains(" comment")) { - //20200518 zhengkai 修复包含comment关键字的问题 - String commentTmp = columnLine.substring(columnLine.lastIndexOf("comment") + 7).trim().get(); - // '用户ID', - if (commentTmp.contains("`") || commentTmp.indexOf("`") != commentTmp.lastIndexOf("`")) { - commentTmp = commentTmp.substring(commentTmp.indexOf("`") + 1, commentTmp.lastIndexOf("`")); - } - //解决最后一句是评论,无主键且连着)的问题:album_id int(3) default '1' null comment '相册id:0 代表头像 1代表照片墙') - if (commentTmp.contains(")")) { - commentTmp = commentTmp.substring(0, commentTmp.lastIndexOf(")") + 1); - } - fieldComment = commentTmp; - } else { - //修复comment不存在导致报错的问题 - fieldComment = columnName; - } - - FieldInfo fieldInfo = new FieldInfo(); - // - fieldInfo.setColumnName(columnName); - fieldInfo.setFieldName(fieldName); - fieldInfo.setFieldClass(fieldClass); - fieldInfo.setSwaggerClass(swaggerClass); - fieldInfo.setFieldComment(fieldComment); - - fieldList.add(fieldInfo); - } - } - } - - if (fieldList.size() < 1) { - throw new CodeGenerateException("表结构分析失败,请检查语句或者提交issue给我"); - } - - ClassInfo codeJavaInfo = new ClassInfo(); - codeJavaInfo.setTableName(tableName); - codeJavaInfo.setClassName(className); - codeJavaInfo.setClassComment(classComment); - codeJavaInfo.setFieldList(fieldList); - codeJavaInfo.setOriginTableName(originTableName); - - return codeJavaInfo; - } - - private static boolean isNotSpecialColumnLine(NonCaseString columnLine, int lineSeq) { - return ( - !columnLine.containsAny( - "key ", - "constraint", - " using ", - "unique ", - "fulltext ", - "index ", - "pctincrease", - "buffer_pool", - "tablespace" - ) - && !(columnLine.contains("primary ") && columnLine.indexOf("storage") + 3 > columnLine.indexOf("(")) - && !(columnLine.contains("primary ") && lineSeq > 3) - ); - } - - /** - * 解析JSON生成类信息 - * - * @param paramInfo - * @return - */ - public static ClassInfo processJsonToClassInfo(ParamInfo paramInfo) { - ClassInfo codeJavaInfo = new ClassInfo(); - codeJavaInfo.setTableName("JsonDto"); - codeJavaInfo.setClassName("JsonDto"); - codeJavaInfo.setClassComment("JsonDto"); - - //support children json if forget to add '{' in front of json - if (paramInfo.getTableSql().trim().startsWith("\"")) { - paramInfo.setTableSql("{" + paramInfo.getTableSql()); - } - if (JSON.isValid(paramInfo.getTableSql())) { - if (paramInfo.getTableSql().trim().startsWith("{")) { - JSONObject jsonObject = JSONObject.parseObject(paramInfo.getTableSql().trim()); - //parse FieldList by JSONObject - codeJavaInfo.setFieldList(processJsonObjectToFieldList(jsonObject)); - } else if (paramInfo.getTableSql().trim().startsWith("[")) { - JSONArray jsonArray = JSONArray.parseArray(paramInfo.getTableSql().trim()); - //parse FieldList by JSONObject - codeJavaInfo.setFieldList(processJsonObjectToFieldList(jsonArray.getJSONObject(0))); - } - } - - return codeJavaInfo; - } - - /** - * parse SQL by regex - * - * @param paramInfo - * @return - * @author https://github.com/ydq - */ - public static ClassInfo processTableToClassInfoByRegex(ParamInfo paramInfo) { - // field List - List fieldList = new ArrayList(); - //return classInfo - ClassInfo codeJavaInfo = new ClassInfo(); - - //匹配整个ddl,将ddl分为表名,列sql部分,表注释 - String DDL_PATTEN_STR = "\\s*create\\s+table\\s+(?\\S+)[^\\(]*\\((?[\\s\\S]+)\\)[^\\)]+?(comment\\s*(=|on\\s+table)\\s*'(?.*?)'\\s*;?)?$"; - - Pattern DDL_PATTERN = Pattern.compile(DDL_PATTEN_STR, Pattern.CASE_INSENSITIVE); - - //匹配列sql部分,分别解析每一列的列名 类型 和列注释 - String COL_PATTERN_STR = "\\s*(?\\S+)\\s+(?\\w+)\\s*(?:\\([\\s\\d,]+\\))?((?!comment).)*(comment\\s*'(?.*?)')?\\s*(,|$)"; - - Pattern COL_PATTERN = Pattern.compile(COL_PATTERN_STR, Pattern.CASE_INSENSITIVE); - - Matcher matcher = DDL_PATTERN.matcher(paramInfo.getTableSql().trim()); - if (matcher.find()) { - String tableName = matcher.group("tableName"); - String tableComment = matcher.group("tableComment"); - codeJavaInfo.setTableName(tableName.replaceAll("'", "")); - codeJavaInfo.setClassName(tableName.replaceAll("'", "")); - codeJavaInfo.setClassComment(tableComment.replaceAll("'", "")); - String columnsSQL = matcher.group("columnsSQL"); - if (columnsSQL != null && columnsSQL.length() > 0) { - Matcher colMatcher = COL_PATTERN.matcher(columnsSQL); - while (colMatcher.find()) { - String fieldName = colMatcher.group("fieldName"); - String fieldType = colMatcher.group("fieldType"); - String fieldComment = colMatcher.group("fieldComment"); - if (!"key".equalsIgnoreCase(fieldType)) { - FieldInfo fieldInfo = new FieldInfo(); - fieldInfo.setFieldName(fieldName.replaceAll("'", "")); - fieldInfo.setColumnName(fieldName.replaceAll("'", "")); - fieldInfo.setFieldClass(fieldType.replaceAll("'", "")); - fieldInfo.setFieldComment(fieldComment.replaceAll("'", "")); - fieldList.add(fieldInfo); - } - } - } - codeJavaInfo.setFieldList(fieldList); - } - return codeJavaInfo; - } - - public static List processJsonObjectToFieldList(JSONObject jsonObject) { - // field List - List fieldList = new ArrayList(); - jsonObject.keySet().stream().forEach(jsonField -> { - FieldInfo fieldInfo = new FieldInfo(); - fieldInfo.setFieldName(jsonField); - fieldInfo.setColumnName(jsonField); - fieldInfo.setFieldClass(String.class.getSimpleName()); - fieldInfo.setFieldComment("father:" + jsonField); - fieldList.add(fieldInfo); - if (jsonObject.get(jsonField) instanceof JSONArray) { - jsonObject.getJSONArray(jsonField).stream().forEach(arrayObject -> { - FieldInfo fieldInfo2 = new FieldInfo(); - fieldInfo2.setFieldName(arrayObject.toString()); - fieldInfo2.setColumnName(arrayObject.toString()); - fieldInfo2.setFieldClass(String.class.getSimpleName()); - fieldInfo2.setFieldComment("children:" + arrayObject.toString()); - fieldList.add(fieldInfo2); - }); - } else if (jsonObject.get(jsonField) instanceof JSONObject) { - jsonObject.getJSONObject(jsonField).keySet().stream().forEach(arrayObject -> { - FieldInfo fieldInfo2 = new FieldInfo(); - fieldInfo2.setFieldName(arrayObject.toString()); - fieldInfo2.setColumnName(arrayObject.toString()); - fieldInfo2.setFieldClass(String.class.getSimpleName()); - fieldInfo2.setFieldComment("children:" + arrayObject.toString()); - fieldList.add(fieldInfo2); - }); - } - }); - if (fieldList.size() < 1) { - throw new CodeGenerateException("JSON解析失败"); - } - return fieldList; - } - - public static ClassInfo processInsertSqlToClassInfo(ParamInfo paramInfo) { - // field List - List fieldList = new ArrayList(); - //return classInfo - ClassInfo codeJavaInfo = new ClassInfo(); - - //get origin sql - String fieldSqlStr = paramInfo.getTableSql().toLowerCase().trim(); - fieldSqlStr = fieldSqlStr.replaceAll(" ", " ").replaceAll("\\\\n`", "") - .replaceAll("\\+", "").replaceAll("``", "`").replaceAll("\\\\", ""); - String valueStr = fieldSqlStr.substring(fieldSqlStr.lastIndexOf("values") + 6).replaceAll(" ", "").replaceAll("\\(", "").replaceAll("\\)", ""); - //get the string between insert into and values - fieldSqlStr = fieldSqlStr.substring(0, fieldSqlStr.lastIndexOf("values")); - - System.out.println(fieldSqlStr); - - String insertSqlPattenStr = "insert into (?.*) \\((?.*)\\)"; - //String DDL_PATTEN_STR="\\s*create\\s+table\\s+(?\\S+)[^\\(]*\\((?[\\s\\S]+)\\)[^\\)]+?(comment\\s*(=|on\\s+table)\\s*'(?.*?)'\\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 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; - } } diff --git a/generator-web/src/main/resources/application-bejson.yml b/generator-web/src/main/resources/application-bejson.yml index 04cfe67..5590268 100644 --- a/generator-web/src/main/resources/application-bejson.yml +++ b/generator-web/src/main/resources/application-bejson.yml @@ -1,5 +1,7 @@ server: port: 1234 + http2: + enabled: true servlet: context-path: /generator #tomcat: @@ -8,7 +10,7 @@ server: # max-threads: 10 # background-processor-delay: 30 # basedir: ${user.home}/tomcat/ - undertow: +undertow: # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程 # 不要设置过大,如果过大,启动项目会报错:打开文件数过多 io-threads: 4 @@ -23,7 +25,7 @@ server: spring: banner: charset: UTF-8 - http: + web: encoding: force: true charset: UTF-8 @@ -47,12 +49,12 @@ spring: #mvc: # static-path-pattern: /statics/** OEM: - version: 2024.4 + version: 2024.12 header: SQL转Java JPA、MYBATIS实现类代码生成平台 keywords: sql转实体类,sql转DAO,SQL转service,SQL转JPA实现,SQL转MYBATIS实现 title: JAVA在线代码生成 - slogan: For reducing the repetitive CRUD work - description:

SpringBootCodeGenerator(JAVA代码生成平台),
又名`大狼狗代码生成器`、`SQL转JAVA`、`SQL转JPA`、`SQL转Mybatis`、`Mybatis在线生成器`、`SQL转Java JPA、MYBATIS实现类代码生成平台`。

——以解放双手为目的,减少大量的重复CRUD工作,可通过建表SQL语句生成JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL/CommonMapper等相关模板代码。

+ slogan: Release your hands from tedious and repetitive CRUD tasks. + description:

SpringBootCodeGenerator(JAVA代码生成平台),
又名`大狼狗代码生成器`、`SQL转JAVA`、`SQL转JPA`、`SQL转Mybatis`、`Mybatis在线生成器`、`SQL转Java JPA、MYBATIS实现类代码生成平台`。

——从繁琐重复的`CRUD工作`中释放你的双手,可通过DDL SQL语句或Select SQL语句或简单Json->生成JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL/CommonMapper等相关模板代码。

author: BEJSON packageName: www.bejson.com copyright: Powered by Moshow郑锴 , Might the holy light be with you ! diff --git a/generator-web/src/main/resources/application-dev.yml b/generator-web/src/main/resources/application-dev.yml index 2b06145..6b05721 100644 --- a/generator-web/src/main/resources/application-dev.yml +++ b/generator-web/src/main/resources/application-dev.yml @@ -47,12 +47,12 @@ spring: #mvc: # static-path-pattern: /statics/** OEM: - version: 2024.4 + version: 2024.12 header: SQL转Java JPA、MYBATIS实现类代码生成平台 keywords: sql转实体类,sql转DAO,SQL转service,SQL转JPA实现,SQL转MYBATIS实现 title: JAVA代码生成平台 - slogan: For reducing the repetitive CRUD work - description:

SpringBootCodeGenerator(JAVA代码生成平台),
又名`大狼狗代码生成器`、`SQL转JAVA`、`SQL转JPA`、`SQL转Mybatis`、`Mybatis在线生成器`、`SQL转Java JPA、MYBATIS实现类代码生成平台`。

——以解放双手为目的,减少大量的重复CRUD工作,可通过建表SQL语句生成JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL/CommonMapper等相关模板代码。

+ slogan: Release your hands from tedious and repetitive CRUD tasks. + description:

SpringBootCodeGenerator(JAVA代码生成平台),
又名`大狼狗代码生成器`、`SQL转JAVA`、`SQL转JPA`、`SQL转Mybatis`、`Mybatis在线生成器`、`SQL转Java JPA、MYBATIS实现类代码生成平台`。

——从繁琐重复的`CRUD工作`中释放你的双手,可通过DDL SQL语句或Select SQL语句或简单Json->生成JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL/CommonMapper等相关模板代码。

author: Zhengkai.blog.csdn.net packageName: com.software.system copyright: Powered by Moshow郑锴 , Might the holy light be with you ! diff --git a/generator-web/src/main/resources/statics/js/main.js b/generator-web/src/main/resources/statics/js/main.js index 3cd412d..8fd3d08 100644 --- a/generator-web/src/main/resources/statics/js/main.js +++ b/generator-web/src/main/resources/statics/js/main.js @@ -123,7 +123,7 @@ const vm = new Vue({ vm.formData.tableSql=$.inputArea.getValue(); axios.post(basePath+"/code/generate",vm.formData).then(function(res){ if(res.code===500){ - error("生成失败"); + error("生成失败,请检查SQL语句!!!"); return; } setAllCookie(); diff --git a/generator-web/src/main/resources/statics/version.json b/generator-web/src/main/resources/statics/version.json deleted file mode 100644 index deefb3d..0000000 --- a/generator-web/src/main/resources/statics/version.json +++ /dev/null @@ -1 +0,0 @@ -{"version": "20231022"} \ No newline at end of file diff --git a/generator-web/src/main/resources/templates/header-CDN-v2.html b/generator-web/src/main/resources/templates/header-CDN-v2.html index cb1b80d..fe77ab7 100644 --- a/generator-web/src/main/resources/templates/header-CDN-v2.html +++ b/generator-web/src/main/resources/templates/header-CDN-v2.html @@ -3,43 +3,43 @@ - - - - - + + + + + - + - + - + - - - - - - - + + + + + + + - + - + - \ No newline at end of file + \ No newline at end of file diff --git a/generator-web/src/main/resources/templates/index.html b/generator-web/src/main/resources/templates/index.html index efd12cb..8701ce7 100644 --- a/generator-web/src/main/resources/templates/index.html +++ b/generator-web/src/main/resources/templates/index.html @@ -6,8 +6,8 @@ by https://zhengkai.blog.csdn.net - JAVA代码生成平台 <#include "/header.html"> + ${(value.title)!!}
@@ -17,7 +17,7 @@ by https://zhengkai.blog.csdn.net
AdminLTE Logo - JAVA代码生成平台 + ${(value.title)!!} diff --git a/generator-web/src/main/resources/templates/main-v2.html b/generator-web/src/main/resources/templates/main-v2.html index 2423e8a..12cf120 100644 --- a/generator-web/src/main/resources/templates/main-v2.html +++ b/generator-web/src/main/resources/templates/main-v2.html @@ -80,6 +80,7 @@ + diff --git a/generator-web/src/test/java/FooTest.java b/generator-web/src/test/java/FooTest.java deleted file mode 100644 index bbdff21..0000000 --- a/generator-web/src/test/java/FooTest.java +++ /dev/null @@ -1,27 +0,0 @@ -import com.softdev.system.generator.util.StringUtils; - -public class FooTest { - - public static void main(String[] args) { - // String updateTime = StringUtils.underlineToCamelCase("updateTime"); - // System.out.println(updateTime); - - - // System.out.println(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, "userName")); - // System.out.println(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, "userNAme-UUU")); - - System.out.println(StringUtils.toUnderline("userName",false)); - System.out.println(StringUtils.toUnderline("UserName",false)); - System.out.println(StringUtils.toUnderline("user_NameGgg_x-UUU",false)); - System.out.println(StringUtils.toUnderline("username",false)); - - System.out.println(StringUtils.toUnderline("userName",true)); - System.out.println(StringUtils.toUnderline("UserName",true)); - System.out.println(StringUtils.toUnderline("user_NameGgg_x-UUU",true)); - System.out.println(StringUtils.toUnderline("username",true)); - - System.out.println(StringUtils.underlineToCamelCase("CREATE_TIME")); - } - - -} diff --git a/generator-web/src/test/java/com/softdev/system/generator/util/StringUtilsPlusTest.java b/generator-web/src/test/java/com/softdev/system/generator/util/StringUtilsPlusTest.java new file mode 100644 index 0000000..1df912a --- /dev/null +++ b/generator-web/src/test/java/com/softdev/system/generator/util/StringUtilsPlusTest.java @@ -0,0 +1,104 @@ +package com.softdev.system.generator.util; + +import org.junit.Test; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertTrue; +import static org.junit.Assert.assertFalse; + +public class StringUtilsPlusTest { + + @Test + public void toLowerCamel() { + System.out.println(StringUtilsPlus.toLowerCamel("hello_world")); + System.out.println(StringUtilsPlus.toLowerCamel("HELLO_WO-RLD-IK")); + System.out.println(StringUtilsPlus.toLowerCamel("HELLO_WORLD-IKabc")); + System.out.println(StringUtilsPlus.toLowerCamel("HELLO-WORLD-IKabc")); + System.out.println(StringUtilsPlus.toLowerCamel("HELLO-123WORLD-IKabc")); + System.out.println(StringUtilsPlus.toLowerCamel("helloWorldOKla")); + assertEquals("helloWorldChina", StringUtilsPlus.toLowerCamel("hello_-_world-cHina")); + } + + @Test + public void upperCaseFirstShouldReturnStringWithFirstLetterCapitalized() { + assertEquals("Hello", StringUtilsPlus.upperCaseFirst("hello")); + } + + @Test + public void upperCaseFirstShouldReturnEmptyStringWhenInputIsEmpty() { + assertEquals("", StringUtilsPlus.upperCaseFirst("")); + } + + @Test + public void lowerCaseFirstShouldReturnStringWithFirstLetterLowercased() { + assertEquals("hello", StringUtilsPlus.lowerCaseFirst("Hello")); + } + + @Test + public void lowerCaseFirstShouldReturnEmptyStringWhenInputIsEmpty() { + assertEquals("", StringUtilsPlus.lowerCaseFirst("")); + } + + @Test + public void underlineToCamelCaseShouldReturnCamelCaseString() { + assertEquals("helloWorld", StringUtilsPlus.underlineToCamelCase("hello_world")); + } + + @Test + public void underlineToCamelCaseShouldReturnEmptyStringWhenInputIsEmpty() { + assertEquals("", StringUtilsPlus.underlineToCamelCase("")); + } + + @Test + public void toUnderlineShouldReturnUnderlinedString() { + assertEquals("hello_world", StringUtilsPlus.toUnderline("helloWorld", false)); + } + + @Test + public void toUnderlineShouldReturnEmptyStringWhenInputIsEmpty() { + assertEquals("", StringUtilsPlus.toUnderline("", false)); + } + + @Test + public void toCamelShouldReturnCamelCaseString() { + assertEquals("helloWorld", StringUtilsPlus.toLowerCamel("hello_world")); + } + + @Test + public void toCamelShouldReturnEmptyStringWhenInputIsEmpty() { + assertEquals("", StringUtilsPlus.toLowerCamel("")); + } + + @Test + public void isNotNullShouldReturnTrueWhenStringIsNotEmpty() { + assertTrue(StringUtilsPlus.isNotNull("hello")); + } + + @Test + public void isNotNullShouldReturnFalseWhenStringIsEmpty() { + assertFalse(StringUtilsPlus.isNotNull("")); + } + + + public static void main(String[] args) { + // String updateTime = StringUtils.underlineToCamelCase("updateTime"); + // System.out.println(updateTime); + + + // System.out.println(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, "userName")); + // System.out.println(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, "userNAme-UUU")); + + System.out.println(StringUtilsPlus.toUnderline("userName",false)); + System.out.println(StringUtilsPlus.toUnderline("UserName",false)); + System.out.println(StringUtilsPlus.toUnderline("user_NameGgg_x-UUU",false)); + System.out.println(StringUtilsPlus.toUnderline("username",false)); + + System.out.println(StringUtilsPlus.toUnderline("userName",true)); + System.out.println(StringUtilsPlus.toUnderline("UserName",true)); + System.out.println(StringUtilsPlus.toUnderline("user_NameGgg_x-UUU",true)); + System.out.println(StringUtilsPlus.toUnderline("username",true)); + + System.out.println(StringUtilsPlus.underlineToCamelCase("CREATE_TIME")); + } + +} diff --git a/generator-web/src/test/java/com/softdev/system/generator/util/StringUtilsTest.java b/generator-web/src/test/java/com/softdev/system/generator/util/StringUtilsTest.java deleted file mode 100644 index b7fbdca..0000000 --- a/generator-web/src/test/java/com/softdev/system/generator/util/StringUtilsTest.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.softdev.system.generator.util; - -import org.junit.Test; - -import static junit.framework.TestCase.assertEquals; -import static junit.framework.TestCase.assertTrue; -import static org.junit.Assert.assertFalse; - -public class StringUtilsTest { - - @Test - public void toLowerCamel() { - System.out.println(StringUtils.toLowerCamel("hello_world")); - System.out.println(StringUtils.toLowerCamel("HELLO_WO-RLD-IK")); - System.out.println(StringUtils.toLowerCamel("HELLO_WORLD-IKabc")); - System.out.println(StringUtils.toLowerCamel("HELLO-WORLD-IKabc")); - System.out.println(StringUtils.toLowerCamel("HELLO-123WORLD-IKabc")); - System.out.println(StringUtils.toLowerCamel("helloWorldOKla")); - assertEquals("helloWorldChina", StringUtils.toLowerCamel("hello_-_world-cHina")); - } - - @Test - public void upperCaseFirstShouldReturnStringWithFirstLetterCapitalized() { - assertEquals("Hello", StringUtils.upperCaseFirst("hello")); - } - - @Test - public void upperCaseFirstShouldReturnEmptyStringWhenInputIsEmpty() { - assertEquals("", StringUtils.upperCaseFirst("")); - } - - @Test - public void lowerCaseFirstShouldReturnStringWithFirstLetterLowercased() { - assertEquals("hello", StringUtils.lowerCaseFirst("Hello")); - } - - @Test - public void lowerCaseFirstShouldReturnEmptyStringWhenInputIsEmpty() { - assertEquals("", StringUtils.lowerCaseFirst("")); - } - - @Test - public void underlineToCamelCaseShouldReturnCamelCaseString() { - assertEquals("helloWorld", StringUtils.underlineToCamelCase("hello_world")); - } - - @Test - public void underlineToCamelCaseShouldReturnEmptyStringWhenInputIsEmpty() { - assertEquals("", StringUtils.underlineToCamelCase("")); - } - - @Test - public void toUnderlineShouldReturnUnderlinedString() { - assertEquals("hello_world", StringUtils.toUnderline("helloWorld", false)); - } - - @Test - public void toUnderlineShouldReturnEmptyStringWhenInputIsEmpty() { - assertEquals("", StringUtils.toUnderline("", false)); - } - - @Test - public void toCamelShouldReturnCamelCaseString() { - assertEquals("helloWorld", StringUtils.toLowerCamel("hello_world")); - } - - @Test - public void toCamelShouldReturnEmptyStringWhenInputIsEmpty() { - assertEquals("", StringUtils.toLowerCamel("")); - } - - @Test - public void isNotNullShouldReturnTrueWhenStringIsNotEmpty() { - assertTrue(StringUtils.isNotNull("hello")); - } - - @Test - public void isNotNullShouldReturnFalseWhenStringIsEmpty() { - assertFalse(StringUtils.isNotNull("")); - } -} diff --git a/pom.xml b/pom.xml index 16071f8..5405e26 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ org.springframework.boot spring-boot-starter-parent - 3.2.5 + 3.4.1 @@ -28,6 +28,13 @@ + + + com.github.jsqlparser + jsqlparser + 5.0 + + org.springframework.boot spring-boot-starter-web @@ -56,18 +63,18 @@ com.alibaba.fastjson2 fastjson2 - 2.0.49 + 2.0.53 com.alibaba.fastjson2 fastjson2-extension - 2.0.49 + 2.0.53 com.alibaba.fastjson2 fastjson2-extension-spring6 - 2.0.49 + 2.0.53 @@ -103,7 +110,7 @@ org.projectlombok lombok - 1.18.32 + 1.18.36 @@ -130,13 +137,13 @@ org.apache.commons commons-lang3 - 3.14.0 + 3.17.0 commons-io commons-io - 2.16.1 + 2.18.0