JSqlParser Engine全新升级,目前Select SQL模式相对稳定!

This commit is contained in:
Moshow郑锴 2025-09-14 00:40:39 +08:00
parent 2e74d50296
commit 995e1e608a
8 changed files with 100 additions and 75 deletions

View File

@ -70,13 +70,12 @@
# 更新预告
1.计划加入AI来帮忙生成更多样式的模板
2.计划使用AI来改善现有模板
3.深度支持Select SQL模式以及探索JSON模式更多可能
2.改进JSqlParser Engine (Select SQL and Create SQL)
# Update Logs
| 更新日期 | 更新内容 |
|:-----------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 2025.09.13 | Create SQL by JSqlParser Engine升级<br>更新SpringBoot等类库版本修复漏洞<br>修复CDN问题切换为staticfile.org |
| 2025.09.13 | JSqlParser Engine全新升级目前Select SQL模式相对稳定! <br>更新SpringBoot等类库版本修复漏洞<br>修复CDN问题切换为staticfile.org |
| 2025.03.31 | 优化说明 |
| 2025.03.16 | NewUI V2前端优化<br>移除不必要内容优化Local和CDN静态文件引入。<br><br>修复由于SQL类型大写导致无法转换的问题。感谢@zzy-design的反馈<br><br>JPA模板优化感谢@PenroseYang的反馈<br>修复不开启Lombok情况下Set/Get方法生成问题;<br>修复importDdate判断为true后没有引入日期类的问题<br> |
| 2024.12.29 | 优化前端加载速度优化输出代码着色CDN改字节跳动静态资源公共库。<br> |

View File

@ -88,7 +88,7 @@ public class GeneratorController {
classInfo = generatorService.generateSelectSqlBySQLPraser(paramInfo);
break;
case "create-sql":
//SelectSqlBySQLPraser模式:parse select sql by JSqlParser
//CreateSqlBySQLPraser模式:parse create sql by JSqlParser
classInfo = generatorService.generateCreateSqlBySQLPraser(paramInfo);
break;
default:

View File

@ -96,6 +96,7 @@ public class GeneratorServiceImpl implements GeneratorService {
if (!CollectionUtils.isEmpty(tableNameList)) {
String tableName = tableNameList.get(0).trim();
classInfo.setTableName(tableName);
classInfo.setOriginTableName(tableName);
String className = StringUtilsPlus.upperCaseFirst(StringUtilsPlus.underlineToCamelCase(tableName));
if (className.contains("_")) {
className = className.replaceAll("_", "");
@ -121,21 +122,15 @@ public class GeneratorServiceImpl implements GeneratorService {
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:
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;
}
StringUtilsPlus.toLowerCamel(aliasName);
case ParamInfo.NAME_CASE_TYPE.UNDER_SCORE_CASE -> StringUtilsPlus.toUnderline(aliasName, false);
case ParamInfo.NAME_CASE_TYPE.UPPER_UNDER_SCORE_CASE ->
StringUtilsPlus.toUnderline(aliasName.toUpperCase(), true);
default -> aliasName;
};
//转换后
fieldInfo.setFieldName(fieldName);
@ -157,62 +152,57 @@ public class GeneratorServiceImpl implements GeneratorService {
@Override
public ClassInfo generateCreateSqlBySQLPraser(ParamInfo paramInfo) throws Exception {
ClassInfo classInfo = new ClassInfo();
Statement statement = CCJSqlParserUtil.parse(paramInfo.getTableSql());
CCJSqlParserManager parserManager = new CCJSqlParserManager();
statement = parserManager.parse(new StringReader(paramInfo.getTableSql()));
TablesNamesFinder tablesNamesFinder = new TablesNamesFinder(); // 创建表名发现者对象
List<String> tableNameList = tablesNamesFinder.getTableList(statement); // 获取到表名列表
//一般这里应该只解析到一个表名除非多个表名取第一个
if (!CollectionUtils.isEmpty(tableNameList)) {
String tableName = tableNameList.get(0).trim();
classInfo.setTableName(tableName);
String className = StringUtilsPlus.upperCaseFirst(StringUtilsPlus.underlineToCamelCase(tableName));
if (className.contains("_")) {
className = className.replaceAll("_", "");
}
classInfo.setClassName(className);
classInfo.setClassComment(paramInfo.getTableSql());
Statement statement = null;
try {
statement = CCJSqlParserUtil.parse(paramInfo.getTableSql().trim());
}catch (Exception e) {
e.printStackTrace();
throw new SqlException("SQL语法错误:"+e.getMessage());
}
//解析查询元素
Select select = null;
select = (Select) CCJSqlParserUtil.parse(paramInfo.getTableSql());
PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
List<SelectItem<?>> selectItems = plainSelect.getSelectItems();
// field List
// 确保是CREATE TABLE语句
if (!(statement instanceof CreateTable createTable)) {
throw new SqlException("检测到SQL语句不是DLL CREATE TABLE语句");
}
// 提取表名
String tableName = createTable.getTable().getName();
classInfo.setTableName(tableName);
String className = StringUtilsPlus.upperCaseFirst(StringUtilsPlus.underlineToCamelCase(tableName));
if (className.contains("_")) {
className = className.replaceAll("_", "");
}
classInfo.setClassName(className);
classInfo.setOriginTableName(tableName);
classInfo.setClassComment(paramInfo.getTableSql());
// 提取字段信息
List<FieldInfo> fieldList = new ArrayList<FieldInfo>();
selectItems.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;
List<ColumnDefinition> columnDefinitions = createTable.getColumnDefinitions();
if (columnDefinitions != null) {
for (ColumnDefinition columnDefinition : columnDefinitions) {
FieldInfo fieldInfo = new FieldInfo();
String columnName = columnDefinition.getColumnName();
fieldInfo.setColumnName(columnName);
fieldInfo.setFieldComment(columnDefinition.toString());
// 根据命名规则转换字段名
String fieldName = switch ((String) paramInfo.getOptions().get("nameCaseType")) {
case ParamInfo.NAME_CASE_TYPE.CAMEL_CASE -> StringUtilsPlus.toLowerCamel(columnName);
case ParamInfo.NAME_CASE_TYPE.UNDER_SCORE_CASE -> StringUtilsPlus.toUnderline(columnName, false);
case ParamInfo.NAME_CASE_TYPE.UPPER_UNDER_SCORE_CASE ->
StringUtilsPlus.toUnderline(columnName.toUpperCase(), true);
default -> columnName;
};
fieldInfo.setFieldName(fieldName);
// 设置字段类型为String因为无法准确推测类型
fieldInfo.setFieldClass("String");
fieldList.add(fieldInfo);
}
//转换后
fieldInfo.setFieldName(fieldName);
//无法推测类型所有都set为String
fieldInfo.setFieldClass("String");
fieldList.add(fieldInfo);
});
}
classInfo.setFieldList(fieldList);
log.info("classInfo:{}", JSON.toJSONString(classInfo));
return classInfo;

View File

@ -0,0 +1,35 @@
package com.softdev.system.generator.util;
import java.io.Serial;
/**
* @author xuxueli 2018-05-02 21:10:28
*/
public class SqlException extends RuntimeException {
@Serial
private static final long serialVersionUID = 42L;
public SqlException() {
super();
}
public SqlException(String msg) {
super(msg);
}
public SqlException(String msg, Throwable cause) {
super(msg, cause);
}
public SqlException(Throwable cause) {
super(cause);
}
public SqlException(String message, Throwable cause,
boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@ -59,4 +59,4 @@ OEM:
returnUtilSuccess: ResponseUtil.success
returnUtilFailure: ResponseUtil.error
outputStr: http://zhengkai.blog.csdn.net
mode: CDN
mode: local

View File

@ -1,3 +1,3 @@
spring:
profiles:
active: bejson
active: dev

View File

@ -123,8 +123,9 @@ const vm = new Vue({
//get value from codemirror
vm.formData.tableSql=$.inputArea.getValue();
axios.post(basePath+"/code/generate",vm.formData).then(function(res){
if(res.code===500){
error("生成失败请检查SQL语句!!!");
if(res.status===500||res.data.code===500){
console.log(res);
error("生成失败请检查SQL语句!!!"+res.data.msg);
return;
}
setAllCookie();

View File

@ -100,7 +100,7 @@
</div>
<div class="card-body">
<el-form-item label="生成引擎">
<el-form-item label="🌟🌟🌟引擎">
<el-select v-model="formData.options.dataType">
<el-option label="DDL SQL@自研SQL解析引擎" value="sql"></el-option>
<el-option label="SELECT SQL@JSqlParser引擎" value="select-sql"></el-option>