mirror of
https://github.com/moshowgame/SpringBootCodeGenerator.git
synced 2025-12-26 05:48:33 +08:00
| 2024.12.23 | 新增InsertSQL模式,采用JSQLParser引擎进行封装<br>优化代码封装<br>CDN恢复为staticfile.org加速(如果本地卡的话,建议切换local模式)。<br>
This commit is contained in:
parent
ea4e612445
commit
1a6e1a3ffb
42
README.md
42
README.md
@ -10,30 +10,31 @@
|
||||
>powered by `Moshow郑锴(大狼狗)` , [https://zhengkai.blog.csdn.net](https://zhengkai.blog.csdn.net)
|
||||
|
||||
# Description
|
||||
>Based on SpringBoot2+Freemarker<br>
|
||||
> #基于`SpringBoot2`和`Freemarker`的代码生成平台
|
||||
>The `Spring Boot Code Generator` , Based on SpringBoot3 and Freemarker<br>
|
||||
> #基于`SpringBoot3`和`Freemarker`的代码生成平台
|
||||
>
|
||||
>For reducing the repetitive CRUD work<br>
|
||||
> #以解放双手为目的,减少大量的`重复CRUD工作`
|
||||
>Release your hands from tedious and repetitive CRUD tasks.<br>
|
||||
> #从繁琐重复的`CRUD工作`中释放你的双手
|
||||
>
|
||||
>Support mysql, oracle and pgsql<br>
|
||||
>Support mysql+oracle+pgsql , the most popular databases standard SQL<br>
|
||||
> #支持`MySQL`、Oracle、PgSQL三大主流数据库
|
||||
>
|
||||
>Generate to many predefined popular templates by DDL-SQL/Insert-SQL/Simple JSON<br>
|
||||
> 可通过`建表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.<br>
|
||||
> 通过建表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 <br>
|
||||
> 感谢大家的使用和反馈,每天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. <br>
|
||||
> 感谢大家的使用与反馈,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. <br>
|
||||
>May everyone maintain a work-life balance, stay healthy and safe. Wishing you all success in your work and continuous advancements!. <br>
|
||||
> 愿大家可以维持生活和工作平衡,保持健康和安全,祝大家工作顺利,步步高升!
|
||||
>Please submit your issue and template , or pull your good idea into the PR <br>
|
||||
> 提交你的问题和生成模板,或者提交你的好主意到PR。
|
||||
>
|
||||
>Welcome to submit your issue and useful templates , or put your good idea into PR <br>
|
||||
> 欢迎提交你的问题和常用有用模板,或者提交你的好主意到PR。
|
||||
|
||||
|
||||
# URL
|
||||
|
||||
- 感谢`卡卡`将他部署在[BEJSON](https://java.bejson.com/generator)上,目前是besjon专供的`金牌工具`(线上版本不一定是最新的,会有延迟,请谅解,谢谢).<br>
|
||||
- 感谢`卡卡`将他部署在[BEJSON](https://java.bejson.com/generator)上,目前是BeJSON专供的`金牌工具`(线上版本不一定是最新的,会有延迟,请谅解,谢谢).<br>
|
||||
- 感谢`jully.top`部署的副本 [https://jully.top/generator/](https://jully.top/generator/)。<br>
|
||||
- 感谢`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) .<br>
|
||||
@ -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进行加速。<br>前端NEWUI改版(基于AdminLTE+Bootstrap+Vue+ElementUI混合模式)。|
|
||||
| 2024.04.22 | [Java CI with Maven](https://github.com/moshowgame/SpringBootCodeGenerator/actions/workflows/maven.yml) 更新<br>SpringBoot升级到3.2.5<br>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引擎进行封装<br>优化代码封装<br>CDN恢复为staticfile.org加速(如果本地卡的话,建议切换local模式)。<br> |
|
||||
| 2024.04.23 | 切换为更快更稳定的BootCDN进行加速。<br>前端NEWUI改版(基于AdminLTE+Bootstrap+Vue+ElementUI混合模式)。 |
|
||||
| 2024.04.22 | [Java CI with Maven](https://github.com/moshowgame/SpringBootCodeGenerator/actions/workflows/maven.yml) 更新<br>SpringBoot升级到3.2.5<br>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)<br>fix 驼峰列名转命名风格错误问题<br>增强转下划线命名风格, 对原始风格不敏感. 支持各种命名风格的列名 to 下划线<br>增加 NonCaseString 大小写不敏感字符串包装类, 简化编码<br>几点代码小优化。 |
|
||||
| 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版本
|
||||
<img src="./newui_version.png">
|
||||
2021 半Vue半JS版本
|
||||
|
||||
@ -46,7 +46,13 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.32</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
|
||||
@ -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());
|
||||
|
||||
|
||||
@ -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";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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<String, String> getResultByParams(Map<String, Object> params) throws IOException, TemplateException;
|
||||
|
||||
Map<String, String> getResultByParams(Map<String, Object> 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);
|
||||
}
|
||||
|
||||
@ -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<SelectItem<?>> columnNameList = select.getSelectItems();
|
||||
log.info("tableName:{}", select.getFromItem().toString());
|
||||
// field List
|
||||
List<FieldInfo> fieldList = new ArrayList<FieldInfo>();
|
||||
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<FieldInfo> fieldList = new ArrayList<FieldInfo>();
|
||||
|
||||
// 正常( ) 内的一定是字段相关的定义。
|
||||
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<FieldInfo> fieldList = new ArrayList<FieldInfo>();
|
||||
//return classInfo
|
||||
ClassInfo codeJavaInfo = new ClassInfo();
|
||||
|
||||
//匹配整个ddl,将ddl分为表名,列sql部分,表注释
|
||||
String DDL_PATTEN_STR = "\\s*create\\s+table\\s+(?<tableName>\\S+)[^\\(]*\\((?<columnsSQL>[\\s\\S]+)\\)[^\\)]+?(comment\\s*(=|on\\s+table)\\s*'(?<tableComment>.*?)'\\s*;?)?$";
|
||||
|
||||
Pattern DDL_PATTERN = Pattern.compile(DDL_PATTEN_STR, Pattern.CASE_INSENSITIVE);
|
||||
|
||||
//匹配列sql部分,分别解析每一列的列名 类型 和列注释
|
||||
String COL_PATTERN_STR = "\\s*(?<fieldName>\\S+)\\s+(?<fieldType>\\w+)\\s*(?:\\([\\s\\d,]+\\))?((?!comment).)*(comment\\s*'(?<fieldComment>.*?)')?\\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<FieldInfo> processJsonObjectToFieldList(JSONObject jsonObject) {
|
||||
// field List
|
||||
List<FieldInfo> fieldList = new ArrayList<FieldInfo>();
|
||||
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<FieldInfo> fieldList = new ArrayList<FieldInfo>();
|
||||
//return classInfo
|
||||
ClassInfo codeJavaInfo = new ClassInfo();
|
||||
|
||||
//get origin sql
|
||||
String fieldSqlStr = paramInfo.getTableSql().toLowerCase().trim();
|
||||
fieldSqlStr = fieldSqlStr.replaceAll(" ", " ").replaceAll("\\\\n`", "")
|
||||
.replaceAll("\\+", "").replaceAll("``", "`").replaceAll("\\\\", "");
|
||||
String valueStr = fieldSqlStr.substring(fieldSqlStr.lastIndexOf("values") + 6).replaceAll(" ", "").replaceAll("\\(", "").replaceAll("\\)", "");
|
||||
//get the string between insert into and values
|
||||
fieldSqlStr = fieldSqlStr.substring(0, fieldSqlStr.lastIndexOf("values"));
|
||||
|
||||
System.out.println(fieldSqlStr);
|
||||
|
||||
String insertSqlPattenStr = "insert into (?<tableName>.*) \\((?<columnsSQL>.*)\\)";
|
||||
//String DDL_PATTEN_STR="\\s*create\\s+table\\s+(?<tableName>\\S+)[^\\(]*\\((?<columnsSQL>[\\s\\S]+)\\)[^\\)]+?(comment\\s*(=|on\\s+table)\\s*'(?<tableComment>.*?)'\\s*;?)?$";
|
||||
|
||||
Matcher matcher1 = Pattern.compile(insertSqlPattenStr).matcher(fieldSqlStr);
|
||||
while (matcher1.find()) {
|
||||
|
||||
String tableName = matcher1.group("tableName");
|
||||
//System.out.println("tableName:"+tableName);
|
||||
codeJavaInfo.setClassName(tableName);
|
||||
codeJavaInfo.setTableName(tableName);
|
||||
|
||||
String columnsSQL = matcher1.group("columnsSQL");
|
||||
//System.out.println("columnsSQL:"+columnsSQL);
|
||||
|
||||
List<String> valueList = new ArrayList<>();
|
||||
//add values as comment
|
||||
Arrays.stream(valueStr.split(",")).forEach(column -> {
|
||||
valueList.add(column);
|
||||
});
|
||||
AtomicInteger n = new AtomicInteger(0);
|
||||
//add column to fleldList
|
||||
Arrays.stream(columnsSQL.replaceAll(" ", "").split(",")).forEach(column -> {
|
||||
FieldInfo fieldInfo2 = new FieldInfo();
|
||||
fieldInfo2.setFieldName(column);
|
||||
fieldInfo2.setColumnName(column);
|
||||
fieldInfo2.setFieldClass(String.class.getSimpleName());
|
||||
if (n.get() < valueList.size()) {
|
||||
fieldInfo2.setFieldComment(column + " , eg." + valueList.get(n.get()));
|
||||
}
|
||||
fieldList.add(fieldInfo2);
|
||||
n.getAndIncrement();
|
||||
});
|
||||
|
||||
}
|
||||
if (fieldList.size() < 1) {
|
||||
throw new CodeGenerateException("INSERT SQL解析失败");
|
||||
}
|
||||
codeJavaInfo.setFieldList(fieldList);
|
||||
return codeJavaInfo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ package com.softdev.system.generator.util;
|
||||
*
|
||||
* @author xuxueli 2018-05-02 20:43:25
|
||||
*/
|
||||
public class StringUtils {
|
||||
public class StringUtilsPlus {
|
||||
|
||||
/**
|
||||
* 首字母大写
|
||||
@ -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<FieldInfo> fieldList = new ArrayList<FieldInfo>();
|
||||
|
||||
// 正常( ) 内的一定是字段相关的定义。
|
||||
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<FieldInfo> fieldList = new ArrayList<FieldInfo>();
|
||||
//return classInfo
|
||||
ClassInfo codeJavaInfo = new ClassInfo();
|
||||
|
||||
//匹配整个ddl,将ddl分为表名,列sql部分,表注释
|
||||
String DDL_PATTEN_STR = "\\s*create\\s+table\\s+(?<tableName>\\S+)[^\\(]*\\((?<columnsSQL>[\\s\\S]+)\\)[^\\)]+?(comment\\s*(=|on\\s+table)\\s*'(?<tableComment>.*?)'\\s*;?)?$";
|
||||
|
||||
Pattern DDL_PATTERN = Pattern.compile(DDL_PATTEN_STR, Pattern.CASE_INSENSITIVE);
|
||||
|
||||
//匹配列sql部分,分别解析每一列的列名 类型 和列注释
|
||||
String COL_PATTERN_STR = "\\s*(?<fieldName>\\S+)\\s+(?<fieldType>\\w+)\\s*(?:\\([\\s\\d,]+\\))?((?!comment).)*(comment\\s*'(?<fieldComment>.*?)')?\\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<FieldInfo> processJsonObjectToFieldList(JSONObject jsonObject) {
|
||||
// field List
|
||||
List<FieldInfo> fieldList = new ArrayList<FieldInfo>();
|
||||
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<FieldInfo> fieldList = new ArrayList<FieldInfo>();
|
||||
//return classInfo
|
||||
ClassInfo codeJavaInfo = new ClassInfo();
|
||||
|
||||
//get origin sql
|
||||
String fieldSqlStr = paramInfo.getTableSql().toLowerCase().trim();
|
||||
fieldSqlStr = fieldSqlStr.replaceAll(" ", " ").replaceAll("\\\\n`", "")
|
||||
.replaceAll("\\+", "").replaceAll("``", "`").replaceAll("\\\\", "");
|
||||
String valueStr = fieldSqlStr.substring(fieldSqlStr.lastIndexOf("values") + 6).replaceAll(" ", "").replaceAll("\\(", "").replaceAll("\\)", "");
|
||||
//get the string between insert into and values
|
||||
fieldSqlStr = fieldSqlStr.substring(0, fieldSqlStr.lastIndexOf("values"));
|
||||
|
||||
System.out.println(fieldSqlStr);
|
||||
|
||||
String insertSqlPattenStr = "insert into (?<tableName>.*) \\((?<columnsSQL>.*)\\)";
|
||||
//String DDL_PATTEN_STR="\\s*create\\s+table\\s+(?<tableName>\\S+)[^\\(]*\\((?<columnsSQL>[\\s\\S]+)\\)[^\\)]+?(comment\\s*(=|on\\s+table)\\s*'(?<tableComment>.*?)'\\s*;?)?$";
|
||||
|
||||
Matcher matcher1 = Pattern.compile(insertSqlPattenStr).matcher(fieldSqlStr);
|
||||
while (matcher1.find()) {
|
||||
|
||||
String tableName = matcher1.group("tableName");
|
||||
//System.out.println("tableName:"+tableName);
|
||||
codeJavaInfo.setClassName(tableName);
|
||||
codeJavaInfo.setTableName(tableName);
|
||||
|
||||
String columnsSQL = matcher1.group("columnsSQL");
|
||||
//System.out.println("columnsSQL:"+columnsSQL);
|
||||
|
||||
List<String> valueList = new ArrayList<>();
|
||||
//add values as comment
|
||||
Arrays.stream(valueStr.split(",")).forEach(column -> {
|
||||
valueList.add(column);
|
||||
});
|
||||
AtomicInteger n = new AtomicInteger(0);
|
||||
//add column to fleldList
|
||||
Arrays.stream(columnsSQL.replaceAll(" ", "").split(",")).forEach(column -> {
|
||||
FieldInfo fieldInfo2 = new FieldInfo();
|
||||
fieldInfo2.setFieldName(column);
|
||||
fieldInfo2.setColumnName(column);
|
||||
fieldInfo2.setFieldClass(String.class.getSimpleName());
|
||||
if (n.get() < valueList.size()) {
|
||||
fieldInfo2.setFieldComment(column + " , eg." + valueList.get(n.get()));
|
||||
}
|
||||
fieldList.add(fieldInfo2);
|
||||
n.getAndIncrement();
|
||||
});
|
||||
|
||||
}
|
||||
if (fieldList.size() < 1) {
|
||||
throw new CodeGenerateException("INSERT SQL解析失败");
|
||||
}
|
||||
codeJavaInfo.setFieldList(fieldList);
|
||||
return codeJavaInfo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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: <p>SpringBootCodeGenerator(JAVA代码生成平台),<br>又名`大狼狗代码生成器`、`SQL转JAVA`、`SQL转JPA`、`SQL转Mybatis`、`Mybatis在线生成器`、`SQL转Java JPA、MYBATIS实现类代码生成平台`。</p><p>——以解放双手为目的,减少大量的重复CRUD工作,可通过建表SQL语句生成JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL/CommonMapper等相关模板代码。</p>
|
||||
slogan: Release your hands from tedious and repetitive CRUD tasks.
|
||||
description: <p>SpringBootCodeGenerator(JAVA代码生成平台),<br>又名`大狼狗代码生成器`、`SQL转JAVA`、`SQL转JPA`、`SQL转Mybatis`、`Mybatis在线生成器`、`SQL转Java JPA、MYBATIS实现类代码生成平台`。</p><p>——从繁琐重复的`CRUD工作`中释放你的双手,可通过DDL SQL语句或Select SQL语句或简单Json->生成JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL/CommonMapper等相关模板代码。</p>
|
||||
author: BEJSON
|
||||
packageName: www.bejson.com
|
||||
copyright: Powered by Moshow郑锴 , Might the holy light be with you !
|
||||
|
||||
@ -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: <p>SpringBootCodeGenerator(JAVA代码生成平台),<br>又名`大狼狗代码生成器`、`SQL转JAVA`、`SQL转JPA`、`SQL转Mybatis`、`Mybatis在线生成器`、`SQL转Java JPA、MYBATIS实现类代码生成平台`。</p><p>——以解放双手为目的,减少大量的重复CRUD工作,可通过建表SQL语句生成JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL/CommonMapper等相关模板代码。</p>
|
||||
slogan: Release your hands from tedious and repetitive CRUD tasks.
|
||||
description: <p>SpringBootCodeGenerator(JAVA代码生成平台),<br>又名`大狼狗代码生成器`、`SQL转JAVA`、`SQL转JPA`、`SQL转Mybatis`、`Mybatis在线生成器`、`SQL转Java JPA、MYBATIS实现类代码生成平台`。</p><p>——从繁琐重复的`CRUD工作`中释放你的双手,可通过DDL SQL语句或Select SQL语句或简单Json->生成JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL/CommonMapper等相关模板代码。</p>
|
||||
author: Zhengkai.blog.csdn.net
|
||||
packageName: com.software.system
|
||||
copyright: Powered by Moshow郑锴 , Might the holy light be with you !
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -1 +0,0 @@
|
||||
{"version": "20231022"}
|
||||
@ -3,43 +3,43 @@
|
||||
<!--#################-->
|
||||
|
||||
<!--jquery | vue | element-ui | axios-->
|
||||
<script src="//cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
|
||||
<script src="//cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
|
||||
<script src="//cdn.bootcdn.net/ajax/libs/element-ui/2.15.14/index.min.js"></script>
|
||||
<link rel="stylesheet" href="//cdn.bootcdn.net/ajax/libs/element-ui/2.15.0/theme-chalk/index.min.css">
|
||||
<script src="//cdn.bootcdn.net/ajax/libs/axios/0.1.0/axios.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/jquery/3.5.1/jquery.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/vue/2.6.12/vue.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/element-ui/2.15.14/index.min.js"></script>
|
||||
<link rel="stylesheet" href="//cdn.staticfile.net/element-ui/2.15.0/theme-chalk/index.min.css">
|
||||
<script src="//cdn.staticfile.net/axios/0.1.0/axios.min.js"></script>
|
||||
|
||||
<!--common.js-->
|
||||
<script src="${request.contextPath}/statics/js/common.js"></script>
|
||||
<!-- <link rel="stylesheet" href="${request.contextPath}/statics/css/main.css"> -->
|
||||
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//cdn.bootcdn.net/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="//cdn.bootcdn.net/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/respond.js/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<!-- Bootstrap 4 -->
|
||||
<script src="//cdn.bootcdn.net/ajax/libs/bootstrap/4.6.2/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/bootstrap/4.6.2/js/bootstrap.bundle.min.js"></script>
|
||||
<!-- AdminLTE 3 -->
|
||||
<script src="//cdn.bootcdn.net/ajax/libs/admin-lte/3.2.0/js/adminlte.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/admin-lte/3.2.0/js/adminlte.min.js"></script>
|
||||
<!-- Toastr 2 -->
|
||||
<script src="//cdn.bootcdn.net/ajax/libs/toastr.js/2.1.4/toastr.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/toastr.js/2.1.4/toastr.min.js"></script>
|
||||
|
||||
<!-- import codemirror -->
|
||||
<script src="//cdn.bootcdn.net/ajax/libs/codemirror/6.65.7/codemirror.min.js"></script>
|
||||
<script src="//cdn.bootcdn.net/ajax/libs/codemirror/6.65.7/mode/sql/sql.min.js"></script>
|
||||
<script src="//cdn.bootcdn.net/ajax/libs/codemirror/6.65.7/mode/xml/xml.min.js"></script>
|
||||
<script src="//cdn.bootcdn.net/ajax/libs/codemirror/6.65.7/mode/clike/clike.min.js"></script>
|
||||
<script src="//cdn.bootcdn.net/ajax/libs/codemirror/6.65.7/mode/javascript/javascript.min.js"></script>
|
||||
<link rel="stylesheet" href="//cdn.bootcdn.net/ajax/libs/codemirror/6.65.7/codemirror.min.css">
|
||||
<link rel="stylesheet" href="//cdn.bootcdn.net/ajax/libs/codemirror/6.65.7/theme/idea.min.css">
|
||||
<script src="//cdn.staticfile.net/codemirror/6.65.7/codemirror.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/codemirror/6.65.7/mode/sql/sql.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/codemirror/6.65.7/mode/xml/xml.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/codemirror/6.65.7/mode/clike/clike.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/codemirror/6.65.7/mode/javascript/javascript.min.js"></script>
|
||||
<link rel="stylesheet" href="//cdn.staticfile.net/codemirror/6.65.7/codemirror.min.css">
|
||||
<link rel="stylesheet" href="//cdn.staticfile.net/codemirror/6.65.7/theme/idea.min.css">
|
||||
|
||||
<!--bootsrap css-->
|
||||
<link rel="stylesheet" href="//cdn.bootcdn.net/ajax/libs/bootstrap/4.6.2/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="//cdn.staticfile.net/bootstrap/4.6.2/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="${request.contextPath}/statics/plugins/fontawesome-free/css/all.min.css">
|
||||
|
||||
<!-- Admin-LTE主题样式 -->
|
||||
<link rel="stylesheet" href="//cdn.bootcdn.net/ajax/libs/admin-lte/3.2.0/css/adminlte.min.css">
|
||||
<link rel="stylesheet" href="//cdn.staticfile.net/admin-lte/3.2.0/css/adminlte.min.css">
|
||||
|
||||
<!-- Toastr CSS -->
|
||||
<link href="//cdn.bootcdn.net/ajax/libs/toastr.js/2.1.4/toastr.min.css" rel="stylesheet">
|
||||
<link href="//cdn.staticfile.net/toastr.js/2.1.4/toastr.min.css" rel="stylesheet">
|
||||
@ -6,8 +6,8 @@ by https://zhengkai.blog.csdn.net
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>JAVA代码生成平台</title>
|
||||
<#include "/header.html">
|
||||
<title>${(value.title)!!}</title>
|
||||
</head>
|
||||
<body class="hold-transition layout-top-nav">
|
||||
<div class="wrapper">
|
||||
@ -17,7 +17,7 @@ by https://zhengkai.blog.csdn.net
|
||||
<div class="container">
|
||||
<a href="#" class="navbar-brand">
|
||||
<img src="${request.contextPath}/statics/img/AdminLTELogo.png" alt="AdminLTE Logo" class="brand-image img-circle elevation-3" style="opacity: .8">
|
||||
<span class="brand-text font-weight-light">JAVA代码生成平台</span>
|
||||
<span class="brand-text font-weight-light">${(value.title)!!}</span>
|
||||
</a>
|
||||
|
||||
<button class="navbar-toggler order-1" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
|
||||
@ -25,7 +25,7 @@ by https://zhengkai.blog.csdn.net
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse order-3" id="navbarCollapse">
|
||||
<i class="fa fa-fw fa-space-shuttle"></i><a>For reducing the repetitive CRUD work</a>
|
||||
<i class="fa fa-fw fa-space-shuttle"></i><a>${(value.slogan)!!}</a>
|
||||
</div>
|
||||
|
||||
<!-- 右侧导航栏链接 -->
|
||||
|
||||
@ -80,6 +80,7 @@
|
||||
<el-option label="DDL SQL" value="sql"></el-option>
|
||||
<el-option label="JSON" value="json"></el-option>
|
||||
<el-option label="INSERT SQL" value="insert-sql">
|
||||
<el-option label="SELECT SQL by SQL Parser" value="select-sql">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
@ -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"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -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"));
|
||||
}
|
||||
|
||||
}
|
||||
@ -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(""));
|
||||
}
|
||||
}
|
||||
21
pom.xml
21
pom.xml
@ -11,7 +11,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.2.5</version>
|
||||
<version>3.4.1</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
@ -28,6 +28,13 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.github.jsqlparser/jsqlparser -->
|
||||
<dependency>
|
||||
<groupId>com.github.jsqlparser</groupId>
|
||||
<artifactId>jsqlparser</artifactId>
|
||||
<version>5.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
@ -56,18 +63,18 @@
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2</artifactId>
|
||||
<version>2.0.49</version>
|
||||
<version>2.0.53</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2-extension</artifactId>
|
||||
<version>2.0.49</version>
|
||||
<version>2.0.53</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2-extension-spring6 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2-extension-spring6</artifactId>
|
||||
<version>2.0.49</version>
|
||||
<version>2.0.53</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api -->
|
||||
@ -103,7 +110,7 @@
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.32</version>
|
||||
<version>1.18.36</version>
|
||||
</dependency>
|
||||
|
||||
<!-- freemarker -->
|
||||
@ -130,13 +137,13 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.14.0</version>
|
||||
<version>3.17.0</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.16.1</version>
|
||||
<version>2.18.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user