diff --git a/src/main/java/com/seeyon/utils/form/FormTableExecutor.java b/src/main/java/com/seeyon/utils/form/FormTableExecutor.java index f4b0145..ac20412 100644 --- a/src/main/java/com/seeyon/utils/form/FormTableExecutor.java +++ b/src/main/java/com/seeyon/utils/form/FormTableExecutor.java @@ -101,7 +101,7 @@ public class FormTableExecutor { param.setConditions(conditions); param.setOrderField(orderField != null ? orderField : ctx.getTableName().contains("formson") ? "sort" : null); param.setSortType(sortType); - Map sqlMap = generateSql(param); + Map sqlMap = SqlGenerator.generateSql(param); JDBCAgent agent = new JDBCAgent(); try { @@ -143,7 +143,7 @@ public class FormTableExecutor { param.setOrderField(orderField != null ? orderField : ctx.getTableName().contains("formson") ? "sort" : null); param.setSortType(sortType); param.setConditions(conditions); - Map sqlMap = generateSql(param); + Map sqlMap = SqlGenerator.generateSql(param); JDBCAgent agent = new JDBCAgent(); try { @@ -194,7 +194,7 @@ public class FormTableExecutor { param.setPageSize(pageSize); param.setOrderField(orderField != null ? orderField : ctx.getTableName().contains("formson") ? "sort" : null); param.setSortType(sortType); - Map sqlMap = generateSql(param);; + Map sqlMap = SqlGenerator.generateSql(param);; JDBCAgent agent = new JDBCAgent(); try { @@ -225,7 +225,7 @@ public class FormTableExecutor { param.setTableName(ctx.getTableName()); param.setConditions(conditions); param.setCountField(countColumn.size() > 0 ? countColumn.get(0) : null); - Map sqlMap = generateSql(param); + Map sqlMap = SqlGenerator.generateSql(param); JDBCAgent agent = new JDBCAgent(); try { @@ -260,7 +260,7 @@ public class FormTableExecutor { param.setTableName(ctx.getTableName()); param.setConditions(conditions); param.setUpdateFields(fields); - Map sqlMap = generateSql(param); + Map sqlMap = SqlGenerator.generateSql(param); JDBCAgent agent = new JDBCAgent(); try { log.info("执行sql为: " + sqlMap.get("sql")); @@ -284,7 +284,7 @@ public class FormTableExecutor { param.setTableName(tableName); param.setConditions(conditions); param.setUpdateFields(fields); - Map sqlMap = generateSql(param); + Map sqlMap = SqlGenerator.generateSql(param); JDBCAgent agent = new JDBCAgent(); try { log.info("执行sql为: " + sqlMap.get("sql")); @@ -309,7 +309,7 @@ public class FormTableExecutor { param.setTableName(ctx.getTableName()); param.setConditions(conditions); - Map sqlMap = generateSql(param); + Map sqlMap = SqlGenerator.generateSql(param); JDBCAgent agent = new JDBCAgent(); try { log.info("执行sql为: " + sqlMap.get("sql")); @@ -401,346 +401,4 @@ public class FormTableExecutor { return value; } - private static Map buildCountSql( - String countField, - String tableName, - List conditions) { - countField = countField == null ? "*" : countField; - StringBuilder sql = new StringBuilder("SELECT count(" + countField + ") as countnum FROM ") - .append(tableName); - - List params = new ArrayList<>(); - sql.append(buildWhereClause(conditions, params)); - - return buildResult(sql, params); - } - - private static Map buildSelectSql( - String tableName, - List queryColumns, - List conditions, - Integer limit, - Integer offset, - String orderField,String sortType) { - String dbName = (String) AppContext.getCache("DATABASE_NAME"); - String orderBy = (orderField == null) ? "start_date" : orderField; - StringBuilder sql = new StringBuilder(); - List params = new ArrayList<>(); - // ===== 1. 构建 SELECT 字段 ===== - StringBuilder selectFields = new StringBuilder(); - if (queryColumns == null || queryColumns.isEmpty()) { - selectFields.append("*"); - } else { - for (int i = 0; i < queryColumns.size(); i++) { - selectFields.append(queryColumns.get(i)); - if (i < queryColumns.size() - 1) { - selectFields.append(","); - } - } - selectFields.append(",ID"); - } - if(sortType == null) { - sortType = "ASC"; - } - // ===== 2. Oracle 分页特殊处理 ===== - if ("oracle".equalsIgnoreCase(dbName) && limit != null && offset != null) { - sql.append("SELECT * FROM ( "); - sql.append(" SELECT t.*, ROW_NUMBER() OVER (ORDER BY ") - .append(orderBy) - .append(" "+ sortType +") rn "); - sql.append(" FROM ") - .append(tableName) - .append(" t "); - sql.append(buildWhereClause(conditions, params)); - sql.append(" ) WHERE rn > ") - .append(offset) - .append(" AND rn <= ") - .append(offset + limit); - } else { - // ===== 3. MySQL / SQLServer 通用逻辑 ===== - sql.append("SELECT ").append(selectFields); - sql.append(" FROM ").append(tableName); - sql.append(buildWhereClause(conditions, params)); - sql.append(" ORDER BY ").append(orderBy).append(" " + sortType); - if (limit != null && offset != null) { - if ("mysql".equalsIgnoreCase(dbName)) { - sql.append(" LIMIT ").append(offset).append(",").append(limit); - } - if ("sqlserver".equalsIgnoreCase(dbName)) { - sql.append(" OFFSET ") - .append(offset) - .append(" ROWS FETCH NEXT ") - .append(limit) - .append(" ROWS ONLY"); - } - } - } - sql.append(";"); - return buildResult(sql, params); - } - - private static Map buildUpdateSql( - String tableName, - List fields, - List conditions) { - - if (fields == null || fields.isEmpty()) { - throw new IllegalArgumentException("Update fields cannot be empty"); - } - if (conditions == null || conditions.isEmpty()) { - throw new IllegalArgumentException("UPDATE must have WHERE conditions"); - } - - StringBuilder sql = new StringBuilder("UPDATE ") - .append(tableName) - .append(" SET "); - - List params = new ArrayList<>(); - int count = 0; - - for (FormUpdateField f : fields) { - if (count++ > 0) { - sql.append(", "); - } - if (f.getValue() instanceof String && ((String) f.getValue()).startsWith("DATE>")) { - sql.append(f.getFieldName()).append(" = TO_DATE(?, 'YYYY-MM-DD')"); - params.add(((String) f.getValue()).substring(5)); - } else { - sql.append(f.getFieldName()).append(" = ?"); - params.add(f.getValue()); - } - } - - if (count == 0) { - throw new IllegalArgumentException("No valid update fields"); - } - - sql.append(buildWhereClause(conditions, params)); - return buildResult(sql, params); - } - - private static Map buildDeleteSql( - String tableName, - List conditions) { - - if (conditions == null || conditions.isEmpty()) { - throw new IllegalArgumentException("DELETE must have WHERE conditions"); - } - - StringBuilder values = new StringBuilder(); - List params = new ArrayList<>(); - - StringBuilder sql = new StringBuilder("DELETE FROM ") - .append(tableName); - - sql.append(buildWhereClause(conditions, params)); - return buildResult(sql, params); - } - - private static Map buildInsertSql( - String tableName, - Map data) { - - if (data == null || data.isEmpty()) { - throw new IllegalArgumentException("Insert data cannot be empty"); - } - - StringBuilder columns = new StringBuilder(); - StringBuilder values = new StringBuilder(); - List params = new ArrayList<>(); - - for (Map.Entry e : data.entrySet()) { - if (columns.length() > 0) { - columns.append(","); - values.append(","); - } - columns.append(e.getKey()); - values.append("?"); - params.add(e.getValue()); - } - - StringBuilder sql = new StringBuilder("INSERT INTO ") - .append(tableName) - .append(" (") - .append(columns) - .append(") VALUES (") - .append(values) - .append(")"); - - return buildResult(sql, params); - } - - /** - * 动态生成 WHERE 子句 - * @param conditions 条件集合 - * @param params 参数列表(引用传递) - * @return 拼接后的 WHERE 子句(包含 WHERE 关键字) - */ - private static String buildWhereClause(List conditions, List params) { - if (conditions == null || conditions.isEmpty()) { - return ""; - } - StringBuilder whereCause = new StringBuilder(" WHERE "); - for (int i = 0; i < conditions.size(); i++) { - FormWhereCondition c = conditions.get(i); - // 左括号 - for (int b = 0; b < c.getStartWithBracket(); b++) { - whereCause.append("("); - } - String field = c.getFieldName(); - // 字段表达式替换 如 CAST(fieldName AS DECIMAL(10,2)) - if (c.getFieldExpression() != null) { - field = c.getFieldExpression().replace("fieldName", field); - } - ClauseFactor factor = c.getClauseFactor(); - // 自定义表达式优先 - if (c.getExpression() != null) { - whereCause.append(c.getExpression()); - if (c.getValue() != null) { - params.add(c.getValue()); - } - if (c.getValues() != null) { - params.addAll(c.getValues()); - } - } else { - String operator = parseOperator(factor); - // NULL / NOT NULL - if (factor.isNullType()) { - whereCause.append(field).append(" ").append(operator); - } else if (factor.isInType()) { - appendInClause(whereCause, field, operator, c.getValue(), params); - } else if (factor == ClauseFactor.FIND_IN_SET) { - whereCause.append("FIND_IN_SET(?, ").append(field).append(")"); - params.add(c.getValue()); - } else if (factor == ClauseFactor.BETWEEN) { - whereCause.append(field).append(" BETWEEN ? AND ?"); - params.add(c.getValue()); - params.add(c.getValues().get(0)); - } else { - String placeholder = "?"; - // 函数模板(如 TO_DATE(?)) - if (c.getIndex() != null) { - placeholder = c.getIndex(); - } - whereCause.append(field).append(" ").append(operator).append(" ").append(placeholder); - if (ClauseFactor.LIKE.equals(factor)) { - params.add("%" + c.getValue() + "%"); - } else { - params.add(c.getValue()); - } - } - } - // 右括号 - for (int b = 0; b < c.getEndWithBracket(); b++) { - whereCause.append(")"); - } - // AND / OR - if (i < conditions.size() - 1) { - whereCause.append(" ").append(c.getConcatFactor()).append(" "); - } - } - return whereCause.toString(); - } - - private static void appendInClause( - StringBuilder sql, - String field, - String operator, - Object value, - List params) { - if (!(value instanceof Collection)) { - throw new IllegalArgumentException("IN 条件的值必须是 Collection"); - } - Collection values = (Collection) value; - if (values.isEmpty()) { - // 防止 SQL 语法错误 - sql.append("1 = 0"); - return; - } - sql.append(field).append(" ").append(operator).append(" ("); - int index = 0; - for (Object v : values) { - if (index > 0) { - sql.append(", "); - } - sql.append("?"); - params.add(v); - index++; - } - sql.append(")"); - } - - /** - * 解析运算符映射(eq -> =, lt -> < 等) - */ - private static String parseOperator(ClauseFactor factor) { - if(factor == null) { - return "="; - } - switch (factor) { - case EQ: return "="; - case GT: return ">"; - case GE: return ">="; - case LT: return "<"; - case LE: return "<="; - case LIKE: return "LIKE"; - case FIND_IN_SET: return "FIND_IN_SET"; - case REGEXP: return "REGEXP"; - case BETWEEN: return "BETWEEN"; - case NULL: return "IS NULL"; // 空值判断 - case NOT_NULL: return "IS NOT NULL"; // 非空判断 - default: throw new UnsupportedOperationException("不支持的运算符: " + factor); - } - } - - private static Map buildResult(StringBuilder sql, List params) { - Map result = new HashMap<>(); - result.put("sql", sql.toString()); - result.put("params", params); - return result; - } - - public static Map generateSql(SqlBuildParam param) { - - if (param == null || param.getSqlType() == null) { - throw new IllegalArgumentException("SqlBuildParam or SqlType cannot be null"); - } - - switch (param.getSqlType()) { - case COUNT: - return buildCountSql( - param.getCountField(), - param.getTableName(), - param.getConditions() - ); - case SELECT: - return buildSelectSql( - param.getTableName(), - param.getQueryColumns(), - param.getConditions(), - param.getLimit(), - param.getOffset(), - param.getOrderField(), - param.getSortType() - ); - case UPDATE: - return buildUpdateSql( - param.getTableName(), - param.getUpdateFields(), - param.getConditions() - ); - case INSERT: - return buildInsertSql( - param.getTableName(), - param.getInsertData() - ); - case DELETE: - return buildDeleteSql( - param.getTableName(), - param.getConditions() - ); - default: - throw new UnsupportedOperationException("Unsupported SqlType: " + param.getSqlType()); - } - } } \ No newline at end of file diff --git a/src/main/java/com/seeyon/utils/form/SqlGenerator.java b/src/main/java/com/seeyon/utils/form/SqlGenerator.java new file mode 100644 index 0000000..bda2180 --- /dev/null +++ b/src/main/java/com/seeyon/utils/form/SqlGenerator.java @@ -0,0 +1,350 @@ +package com.seeyon.utils.form; + +import com.seeyon.ctp.common.AppContext; + +import java.util.*; + +public class SqlGenerator { + + public static Map generateSql(SqlBuildParam param) { + + if (param == null || param.getSqlType() == null) { + throw new IllegalArgumentException("SqlBuildParam or SqlType cannot be null"); + } + + switch (param.getSqlType()) { + case COUNT: + return buildCountSql( + param.getCountField(), + param.getTableName(), + param.getConditions() + ); + case SELECT: + return buildSelectSql( + param.getTableName(), + param.getQueryColumns(), + param.getConditions(), + param.getLimit(), + param.getOffset(), + param.getOrderField(), + param.getSortType() + ); + case UPDATE: + return buildUpdateSql( + param.getTableName(), + param.getUpdateFields(), + param.getConditions() + ); + case INSERT: + return buildInsertSql( + param.getTableName(), + param.getInsertData() + ); + case DELETE: + return buildDeleteSql( + param.getTableName(), + param.getConditions() + ); + default: + throw new UnsupportedOperationException("Unsupported SqlType: " + param.getSqlType()); + } + } + + private static Map buildCountSql( + String countField, + String tableName, + List conditions) { + countField = countField == null ? "*" : countField; + StringBuilder sql = new StringBuilder("SELECT count(" + countField + ") as countnum FROM ") + .append(tableName); + + List params = new ArrayList<>(); + sql.append(buildWhereClause(conditions, params)); + + return buildResult(sql, params); + } + + private static Map buildSelectSql( + String tableName, + List queryColumns, + List conditions, + Integer limit, + Integer offset, + String orderField, String sortType) { + String dbName = (String) AppContext.getCache("DATABASE_NAME"); + String orderBy = (orderField == null) ? "start_date" : orderField; + StringBuilder sql = new StringBuilder(); + List params = new ArrayList<>(); + // ===== 1. 构建 SELECT 字段 ===== + StringBuilder selectFields = new StringBuilder(); + if (queryColumns == null || queryColumns.isEmpty()) { + selectFields.append("*"); + } else { + for (int i = 0; i < queryColumns.size(); i++) { + selectFields.append(queryColumns.get(i)); + if (i < queryColumns.size() - 1) { + selectFields.append(","); + } + } + selectFields.append(",ID"); + } + if (sortType == null) { + sortType = "ASC"; + } + // ===== 2. Oracle 分页特殊处理 ===== + if ("oracle".equalsIgnoreCase(dbName) && limit != null && offset != null) { + sql.append("SELECT * FROM ( "); + sql.append(" SELECT t.*, ROW_NUMBER() OVER (ORDER BY ") + .append(orderBy) + .append(" " + sortType + ") rn "); + sql.append(" FROM ") + .append(tableName) + .append(" t "); + sql.append(buildWhereClause(conditions, params)); + sql.append(" ) WHERE rn > ") + .append(offset) + .append(" AND rn <= ") + .append(offset + limit); + } else { + // ===== 3. MySQL / SQLServer 通用逻辑 ===== + sql.append("SELECT ").append(selectFields); + sql.append(" FROM ").append(tableName); + sql.append(buildWhereClause(conditions, params)); + sql.append(" ORDER BY ").append(orderBy).append(" " + sortType); + if (limit != null && offset != null) { + if ("mysql".equalsIgnoreCase(dbName)) { + sql.append(" LIMIT ").append(offset).append(",").append(limit); + } + if ("sqlserver".equalsIgnoreCase(dbName)) { + sql.append(" OFFSET ") + .append(offset) + .append(" ROWS FETCH NEXT ") + .append(limit) + .append(" ROWS ONLY"); + } + } + } + sql.append(";"); + return buildResult(sql, params); + } + + private static Map buildUpdateSql( + String tableName, + List fields, + List conditions) { + + if (fields == null || fields.isEmpty()) { + throw new IllegalArgumentException("Update fields cannot be empty"); + } + if (conditions == null || conditions.isEmpty()) { + throw new IllegalArgumentException("UPDATE must have WHERE conditions"); + } + + StringBuilder sql = new StringBuilder("UPDATE ") + .append(tableName) + .append(" SET "); + + List params = new ArrayList<>(); + int count = 0; + + for (FormUpdateField f : fields) { + if (count++ > 0) { + sql.append(", "); + } + if (f.getValue() instanceof String && ((String) f.getValue()).startsWith("DATE>")) { + sql.append(f.getFieldName()).append(" = TO_DATE(?, 'YYYY-MM-DD')"); + params.add(((String) f.getValue()).substring(5)); + } else { + sql.append(f.getFieldName()).append(" = ?"); + params.add(f.getValue()); + } + } + + if (count == 0) { + throw new IllegalArgumentException("No valid update fields"); + } + + sql.append(buildWhereClause(conditions, params)); + return buildResult(sql, params); + } + + private static Map buildDeleteSql( + String tableName, + List conditions) { + + if (conditions == null || conditions.isEmpty()) { + throw new IllegalArgumentException("DELETE must have WHERE conditions"); + } + + List params = new ArrayList<>(); + + StringBuilder sql = new StringBuilder("DELETE FROM ") + .append(tableName); + + sql.append(buildWhereClause(conditions, params)); + return buildResult(sql, params); + } + + private static Map buildInsertSql( + String tableName, + Map data) { + + if (data == null || data.isEmpty()) { + throw new IllegalArgumentException("Insert data cannot be empty"); + } + + StringBuilder columns = new StringBuilder(); + StringBuilder values = new StringBuilder(); + List params = new ArrayList<>(); + + for (Map.Entry e : data.entrySet()) { + if (columns.length() > 0) { + columns.append(","); + values.append(","); + } + columns.append(e.getKey()); + values.append("?"); + params.add(e.getValue()); + } + + StringBuilder sql = new StringBuilder("INSERT INTO ") + .append(tableName) + .append(" (") + .append(columns) + .append(") VALUES (") + .append(values) + .append(")"); + + return buildResult(sql, params); + } + + /** + * 动态生成 WHERE 子句 + * @param conditions 条件集合 + * @param params 参数列表(引用传递) + * @return 拼接后的 WHERE 子句(包含 WHERE 关键字) + */ + static String buildWhereClause(List conditions, List params) { + if (conditions == null || conditions.isEmpty()) { + return ""; + } + StringBuilder whereCause = new StringBuilder(" WHERE "); + for (int i = 0; i < conditions.size(); i++) { + FormWhereCondition c = conditions.get(i); + // 左括号 + for (int b = 0; b < c.getStartWithBracket(); b++) { + whereCause.append("("); + } + String field = c.getFieldName(); + // 字段表达式替换 如 CAST(fieldName AS DECIMAL(10,2)) + if (c.getFieldExpression() != null) { + field = c.getFieldExpression().replace("fieldName", field); + } + ClauseFactor factor = c.getClauseFactor(); + // 自定义表达式优先 + if (c.getExpression() != null) { + whereCause.append(c.getExpression()); + if (c.getValue() != null) { + params.add(c.getValue()); + } + if (c.getValues() != null) { + params.addAll(c.getValues()); + } + } else { + String operator = parseOperator(factor); + // NULL / NOT NULL + if (factor.isNullType()) { + whereCause.append(field).append(" ").append(operator); + } else if (factor.isInType()) { + appendInClause(whereCause, field, operator, c.getValue(), params); + } else if (factor == ClauseFactor.FIND_IN_SET) { + whereCause.append("FIND_IN_SET(?, ").append(field).append(")"); + params.add(c.getValue()); + } else if (factor == ClauseFactor.BETWEEN) { + whereCause.append(field).append(" BETWEEN ? AND ?"); + params.add(c.getValue()); + params.add(c.getValues().get(0)); + } else { + String placeholder = "?"; + // 函数模板(如 TO_DATE(?)) + if (c.getIndex() != null) { + placeholder = c.getIndex(); + } + whereCause.append(field).append(" ").append(operator).append(" ").append(placeholder); + if (ClauseFactor.LIKE.equals(factor)) { + params.add("%" + c.getValue() + "%"); + } else { + params.add(c.getValue()); + } + } + } + // 右括号 + for (int b = 0; b < c.getEndWithBracket(); b++) { + whereCause.append(")"); + } + // AND / OR + if (i < conditions.size() - 1) { + whereCause.append(" ").append(c.getConcatFactor()).append(" "); + } + } + return whereCause.toString(); + } + + private static void appendInClause( + StringBuilder sql, + String field, + String operator, + Object value, + List params) { + if (!(value instanceof Collection)) { + throw new IllegalArgumentException("IN 条件的值必须是 Collection"); + } + Collection values = (Collection) value; + if (values.isEmpty()) { + // 防止 SQL 语法错误 + sql.append("1 = 0"); + return; + } + sql.append(field).append(" ").append(operator).append(" ("); + int index = 0; + for (Object v : values) { + if (index > 0) { + sql.append(", "); + } + sql.append("?"); + params.add(v); + index++; + } + sql.append(")"); + } + + /** + * 解析运算符映射(eq -> =, lt -> < 等) + */ + private static String parseOperator(ClauseFactor factor) { + if (factor == null) { + return "="; + } + switch (factor) { + case EQ: return "="; + case GT: return ">"; + case GE: return ">="; + case LT: return "<"; + case LE: return "<="; + case LIKE: return "LIKE"; + case FIND_IN_SET: return "FIND_IN_SET"; + case REGEXP: return "REGEXP"; + case BETWEEN: return "BETWEEN"; + case NULL: return "IS NULL"; + case NOT_NULL: return "IS NOT NULL"; + default: throw new UnsupportedOperationException("不支持的运算符: " + factor); + } + } + + private static Map buildResult(StringBuilder sql, List params) { + Map result = new HashMap<>(); + result.put("sql", sql.toString()); + result.put("params", params); + return result; + } +}