mirror of
https://github.com/moshowgame/SpringBootCodeGenerator.git
synced 2025-12-26 05:48:33 +08:00
JSqlParser Engine全新升级,目前Select SQL模式相对稳定!
This commit is contained in:
parent
2e74d50296
commit
995e1e608a
@ -70,13 +70,12 @@
|
|||||||
|
|
||||||
# 更新预告
|
# 更新预告
|
||||||
1.计划加入AI来帮忙生成更多样式的模板
|
1.计划加入AI来帮忙生成更多样式的模板
|
||||||
2.计划使用AI来改善现有模板
|
2.改进JSqlParser Engine (Select SQL and Create SQL)
|
||||||
3.深度支持Select SQL模式,以及探索JSON模式更多可能
|
|
||||||
|
|
||||||
# Update Logs
|
# 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.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> |
|
| 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> |
|
| 2024.12.29 | 优化前端加载速度,优化输出代码着色,CDN改字节跳动静态资源公共库。<br> |
|
||||||
|
|||||||
@ -88,7 +88,7 @@ public class GeneratorController {
|
|||||||
classInfo = generatorService.generateSelectSqlBySQLPraser(paramInfo);
|
classInfo = generatorService.generateSelectSqlBySQLPraser(paramInfo);
|
||||||
break;
|
break;
|
||||||
case "create-sql":
|
case "create-sql":
|
||||||
//SelectSqlBySQLPraser模式:parse select sql by JSqlParser
|
//CreateSqlBySQLPraser模式:parse create sql by JSqlParser
|
||||||
classInfo = generatorService.generateCreateSqlBySQLPraser(paramInfo);
|
classInfo = generatorService.generateCreateSqlBySQLPraser(paramInfo);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@ -96,6 +96,7 @@ public class GeneratorServiceImpl implements GeneratorService {
|
|||||||
if (!CollectionUtils.isEmpty(tableNameList)) {
|
if (!CollectionUtils.isEmpty(tableNameList)) {
|
||||||
String tableName = tableNameList.get(0).trim();
|
String tableName = tableNameList.get(0).trim();
|
||||||
classInfo.setTableName(tableName);
|
classInfo.setTableName(tableName);
|
||||||
|
classInfo.setOriginTableName(tableName);
|
||||||
String className = StringUtilsPlus.upperCaseFirst(StringUtilsPlus.underlineToCamelCase(tableName));
|
String className = StringUtilsPlus.upperCaseFirst(StringUtilsPlus.underlineToCamelCase(tableName));
|
||||||
if (className.contains("_")) {
|
if (className.contains("_")) {
|
||||||
className = className.replaceAll("_", "");
|
className = className.replaceAll("_", "");
|
||||||
@ -121,21 +122,15 @@ public class GeneratorServiceImpl implements GeneratorService {
|
|||||||
fieldName=fieldName.contains(".")?fieldName.substring(fieldName.indexOf(".")+1):fieldName;
|
fieldName=fieldName.contains(".")?fieldName.substring(fieldName.indexOf(".")+1):fieldName;
|
||||||
//转换前
|
//转换前
|
||||||
fieldInfo.setColumnName(fieldName);
|
fieldInfo.setColumnName(fieldName);
|
||||||
switch ((String) paramInfo.getOptions().get("nameCaseType")) {
|
fieldName = switch ((String) paramInfo.getOptions().get("nameCaseType")) {
|
||||||
case ParamInfo.NAME_CASE_TYPE.CAMEL_CASE:
|
case ParamInfo.NAME_CASE_TYPE.CAMEL_CASE ->
|
||||||
// 2024-1-27 L&J 适配任意(maybe)原始风格转小写驼峰
|
// 2024-1-27 L&J 适配任意(maybe)原始风格转小写驼峰
|
||||||
fieldName = StringUtilsPlus.toLowerCamel(aliasName);
|
StringUtilsPlus.toLowerCamel(aliasName);
|
||||||
break;
|
case ParamInfo.NAME_CASE_TYPE.UNDER_SCORE_CASE -> StringUtilsPlus.toUnderline(aliasName, false);
|
||||||
case ParamInfo.NAME_CASE_TYPE.UNDER_SCORE_CASE:
|
case ParamInfo.NAME_CASE_TYPE.UPPER_UNDER_SCORE_CASE ->
|
||||||
fieldName = StringUtilsPlus.toUnderline(aliasName, false);
|
StringUtilsPlus.toUnderline(aliasName.toUpperCase(), true);
|
||||||
break;
|
default -> aliasName;
|
||||||
case ParamInfo.NAME_CASE_TYPE.UPPER_UNDER_SCORE_CASE:
|
};
|
||||||
fieldName = StringUtilsPlus.toUnderline(aliasName.toUpperCase(), true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fieldName = aliasName;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//转换后
|
//转换后
|
||||||
fieldInfo.setFieldName(fieldName);
|
fieldInfo.setFieldName(fieldName);
|
||||||
|
|
||||||
@ -157,62 +152,57 @@ public class GeneratorServiceImpl implements GeneratorService {
|
|||||||
@Override
|
@Override
|
||||||
public ClassInfo generateCreateSqlBySQLPraser(ParamInfo paramInfo) throws Exception {
|
public ClassInfo generateCreateSqlBySQLPraser(ParamInfo paramInfo) throws Exception {
|
||||||
ClassInfo classInfo = new ClassInfo();
|
ClassInfo classInfo = new ClassInfo();
|
||||||
Statement statement = CCJSqlParserUtil.parse(paramInfo.getTableSql());
|
Statement statement = null;
|
||||||
CCJSqlParserManager parserManager = new CCJSqlParserManager();
|
try {
|
||||||
statement = parserManager.parse(new StringReader(paramInfo.getTableSql()));
|
statement = CCJSqlParserUtil.parse(paramInfo.getTableSql().trim());
|
||||||
TablesNamesFinder tablesNamesFinder = new TablesNamesFinder(); // 创建表名发现者对象
|
}catch (Exception e) {
|
||||||
List<String> tableNameList = tablesNamesFinder.getTableList(statement); // 获取到表名列表
|
e.printStackTrace();
|
||||||
//一般这里应该只解析到一个表名,除非多个表名,取第一个
|
throw new SqlException("SQL语法错误:"+e.getMessage());
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
//解析查询元素
|
|
||||||
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>();
|
List<FieldInfo> fieldList = new ArrayList<FieldInfo>();
|
||||||
selectItems.forEach(t->{
|
List<ColumnDefinition> columnDefinitions = createTable.getColumnDefinitions();
|
||||||
FieldInfo fieldInfo = new FieldInfo();
|
|
||||||
String fieldName = ((Column)t.getExpression()).getColumnName();
|
if (columnDefinitions != null) {
|
||||||
String aliasName = t.getAlias() != null ? t.getAlias().getName() : ((Column)t.getExpression()).getColumnName();
|
for (ColumnDefinition columnDefinition : columnDefinitions) {
|
||||||
//存储原始字段名
|
FieldInfo fieldInfo = new FieldInfo();
|
||||||
fieldInfo.setFieldComment(aliasName);fieldInfo.setColumnName(aliasName);
|
String columnName = columnDefinition.getColumnName();
|
||||||
//处理字段名是t.xxx的情况
|
fieldInfo.setColumnName(columnName);
|
||||||
fieldName=fieldName.contains(".")?fieldName.substring(fieldName.indexOf(".")+1):fieldName;
|
fieldInfo.setFieldComment(columnDefinition.toString());
|
||||||
//转换前
|
|
||||||
fieldInfo.setColumnName(fieldName);
|
// 根据命名规则转换字段名
|
||||||
switch ((String) paramInfo.getOptions().get("nameCaseType")) {
|
String fieldName = switch ((String) paramInfo.getOptions().get("nameCaseType")) {
|
||||||
case ParamInfo.NAME_CASE_TYPE.CAMEL_CASE:
|
case ParamInfo.NAME_CASE_TYPE.CAMEL_CASE -> StringUtilsPlus.toLowerCamel(columnName);
|
||||||
// 2024-1-27 L&J 适配任意(maybe)原始风格转小写驼峰
|
case ParamInfo.NAME_CASE_TYPE.UNDER_SCORE_CASE -> StringUtilsPlus.toUnderline(columnName, false);
|
||||||
fieldName = StringUtilsPlus.toLowerCamel(aliasName);
|
case ParamInfo.NAME_CASE_TYPE.UPPER_UNDER_SCORE_CASE ->
|
||||||
break;
|
StringUtilsPlus.toUnderline(columnName.toUpperCase(), true);
|
||||||
case ParamInfo.NAME_CASE_TYPE.UNDER_SCORE_CASE:
|
default -> columnName;
|
||||||
fieldName = StringUtilsPlus.toUnderline(aliasName, false);
|
};
|
||||||
break;
|
fieldInfo.setFieldName(fieldName);
|
||||||
case ParamInfo.NAME_CASE_TYPE.UPPER_UNDER_SCORE_CASE:
|
|
||||||
fieldName = StringUtilsPlus.toUnderline(aliasName.toUpperCase(), true);
|
// 设置字段类型为String(因为无法准确推测类型)
|
||||||
break;
|
fieldInfo.setFieldClass("String");
|
||||||
default:
|
fieldList.add(fieldInfo);
|
||||||
fieldName = aliasName;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
//转换后
|
}
|
||||||
fieldInfo.setFieldName(fieldName);
|
|
||||||
|
|
||||||
//无法推测类型,所有都set为String
|
|
||||||
fieldInfo.setFieldClass("String");
|
|
||||||
fieldList.add(fieldInfo);
|
|
||||||
});
|
|
||||||
classInfo.setFieldList(fieldList);
|
classInfo.setFieldList(fieldList);
|
||||||
log.info("classInfo:{}", JSON.toJSONString(classInfo));
|
log.info("classInfo:{}", JSON.toJSONString(classInfo));
|
||||||
return classInfo;
|
return classInfo;
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -59,4 +59,4 @@ OEM:
|
|||||||
returnUtilSuccess: ResponseUtil.success
|
returnUtilSuccess: ResponseUtil.success
|
||||||
returnUtilFailure: ResponseUtil.error
|
returnUtilFailure: ResponseUtil.error
|
||||||
outputStr: http://zhengkai.blog.csdn.net
|
outputStr: http://zhengkai.blog.csdn.net
|
||||||
mode: CDN
|
mode: local
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
spring:
|
spring:
|
||||||
profiles:
|
profiles:
|
||||||
active: bejson
|
active: dev
|
||||||
@ -123,8 +123,9 @@ const vm = new Vue({
|
|||||||
//get value from codemirror
|
//get value from codemirror
|
||||||
vm.formData.tableSql=$.inputArea.getValue();
|
vm.formData.tableSql=$.inputArea.getValue();
|
||||||
axios.post(basePath+"/code/generate",vm.formData).then(function(res){
|
axios.post(basePath+"/code/generate",vm.formData).then(function(res){
|
||||||
if(res.code===500){
|
if(res.status===500||res.data.code===500){
|
||||||
error("生成失败,请检查SQL语句!!!");
|
console.log(res);
|
||||||
|
error("生成失败,请检查SQL语句!!!"+res.data.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setAllCookie();
|
setAllCookie();
|
||||||
|
|||||||
@ -100,7 +100,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<el-form-item label="生成引擎">
|
<el-form-item label="🌟🌟🌟引擎">
|
||||||
<el-select v-model="formData.options.dataType">
|
<el-select v-model="formData.options.dataType">
|
||||||
<el-option label="DDL SQL@自研SQL解析引擎" value="sql"></el-option>
|
<el-option label="DDL SQL@自研SQL解析引擎" value="sql"></el-option>
|
||||||
<el-option label="SELECT SQL@JSqlParser引擎" value="select-sql"></el-option>
|
<el-option label="SELECT SQL@JSqlParser引擎" value="select-sql"></el-option>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user