package easydo.technology.utils;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import easydo.technology.AutoIncrementModel;
import easydo.technology.annotation.NotTableField;
import easydo.technology.annotation.TableKey;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ResultSetUtil {
    private static Pattern linePattern = Pattern.compile("_(\\w)");
    private static String suffixBegin = "_begin";
    private static String suffixEnd = "_end";
    private static String suffixLike = "_like";
    private static String suffixNot = "_not";
    private static String suffixIn = "_in";
    private static String suffixNotIn = "_notin";
    private static String suffixNull = "_null";
    private static String suffixNotNull = "_notnull";
    private static String suffixApplySql = "apply_sql";


    /**
     * 下划线转驼峰
     */
    public static String lineToHump(String str) {
        str = str.toLowerCase();
        Matcher matcher = linePattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }


    private static Pattern humpPattern = Pattern.compile("[A-Z]");

    /**
     * 驼峰转下划线,效率比上面高
     */
    public static String humpToLine(String str) {
        Matcher matcher = humpPattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        if (sb.toString().startsWith("_")) {
            sb.deleteCharAt(0);
        }
        return sb.toString();
    }

    public static List<Map<String, Object>> formatResultSetToListMap(ResultSet resultSet) throws SQLException {
        List<Map<String, Object>> resultList = new ArrayList<>();
        while (resultSet.next()) {
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
            Map<String, Object> resultMap = new HashMap<>();
            for (int i = 1; i <= columnCount; i++) {
                String key = lineToHump(metaData.getColumnName(i));
                if (key.endsWith("Time") || key.endsWith("Date")) {
                    resultMap.put(key, formatDateAndTime(key, resultSet.getObject(i)));
                } else {
                    resultMap.put(key, resultSet.getObject(i));
                }
            }
            resultList.add(resultMap);
        }
        return resultList;
    }

    public static <T> List<T> formatResultSetToList(ResultSet resultSet, Class<T> clazz) throws SQLException {
        List<T> resultList = new ArrayList<>();
        while (resultSet.next()) {
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
            JSONObject jsonObject = new JSONObject();
            for (int i = 1; i <= columnCount; i++) {
                String key = lineToHump(metaData.getColumnName(i));
                if (key.endsWith("Time") || key.endsWith("Date")) {
                    jsonObject.put(key, formatDateAndTime(key, resultSet.getObject(i)));
                } else {
                    jsonObject.put(key, resultSet.getObject(i));
                }

            }
            T t = jsonObject.toJavaObject(clazz);
            resultList.add(t);
        }
        return resultList;
    }

    public static List<String> formatResultSetToArr(ResultSet resultSet) throws SQLException {
        List<String> resultList = new ArrayList<>();
        while (resultSet.next()) {
            ResultSetMetaData metaData = resultSet.getMetaData();
            String key = lineToHump(metaData.getColumnName(1));
            if (key.endsWith("Time") || key.endsWith("Date")) {
                Object object = formatDateAndTime(key, resultSet.getObject(1));
                resultList.add(object == null ? "" : object.toString());
            } else {
                resultList.add(resultSet.getObject(1) == null ? "" : resultSet.getObject(1).toString());
            }

        }
        return resultList;
    }

    public static <T> T formatResultSetToModel(ResultSet resultSet, Class<T> clazz) throws SQLException {
        T t;
        JSONObject jsonObject = new JSONObject();
        if (resultSet.next()) {
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
            for (int i = 1; i <= columnCount; i++) {
                String key = lineToHump(metaData.getColumnName(i));
                if (key.endsWith("Time") || key.endsWith("Date")) {
                    jsonObject.put(key, formatDateAndTime(key, resultSet.getObject(i)));
                } else {
                    jsonObject.put(key, resultSet.getObject(i));
                }

            }
        }
        t = jsonObject.toJavaObject(clazz);
        return t;
    }

    private static Object formatDateAndTime(String key, Object object) {
        if (key.endsWith("Time")) {
            try {
                String timeStr = object.toString();
                timeStr = timeStr.replace("T", "").substring(0, 19);
                return timeStr;
            } catch (Exception e) {
                return object;
            }
        } else if (key.endsWith("Date")) {
            try {
                String timeStr = object.toString();
                timeStr = timeStr.substring(0, 10);
                return timeStr;
            } catch (Exception e) {
                return object;
            }
        } else {
            return object;
        }
    }

    public static String formatSqlCondition(Map<String, Object> map) throws RuntimeException {
        String orderLimitSql = formatPageSqlCondition(map);

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(" where 1=1 ");
        map.entrySet().stream()
                .filter(entry -> StringUtil.isNotEmpty(entry.getKey()) && StringUtil.isNotEmpty(entry.getValue()))
                .forEach(entry -> {
                    String key = entry.getKey();
                    Object value = entry.getValue();
                    if (containsSqlInjection(value) && !"apply_sql".equals(key)) {
                        throw new RuntimeException("非法参数");
                    }
                    String column = humpToLine(key);
                    if (column.endsWith(suffixBegin)) {
                        stringBuilder.append(" and ");
                        //解决字段中存在begin和end的情况
                        int lastIndex = column.lastIndexOf(suffixBegin);
                        column = column.substring(0, lastIndex)
                                + column.substring(lastIndex + suffixBegin.length());
                        stringBuilder.append("`").append(column).append("`");
                        stringBuilder.append(">=").append("'").append(value).append("'");
                    } else if (column.endsWith(suffixEnd)) {
                        stringBuilder.append(" and ");
                        //解决字段中存在begin和end的情况
                        int lastIndex = column.lastIndexOf(suffixEnd);
                        column = column.substring(0, lastIndex)
                                + column.substring(lastIndex + suffixEnd.length());
                        stringBuilder.append("`").append(column).append("`");
                        stringBuilder.append("<=").append("'").append(value).append("'");
                    } else if (column.endsWith(suffixLike)) {
                        stringBuilder.append(" and ");
                        int lastIndex = column.lastIndexOf(suffixLike);
                        column = column.substring(0, lastIndex)
                                + column.substring(lastIndex + suffixLike.length());
                        stringBuilder.append("`").append(column).append("`");
                        stringBuilder.append(" like '%").append(value).append("%'");
                    } else if (column.endsWith(suffixNot)) {
                        stringBuilder.append(" and ");
                        int lastIndex = column.lastIndexOf(suffixNot);
                        column = column.substring(0, lastIndex)
                                + column.substring(lastIndex + suffixNot.length());
                        stringBuilder.append("`").append(column).append("`").append("!=");
                        if ("true".equals(value.toString()) || "false".equals(value.toString())) {
                            stringBuilder.append(value);
                        } else {
                            stringBuilder.append("'").append(value).append("'");
                        }
                    } else if (column.endsWith(suffixIn)) {
                        stringBuilder.append(" and ");
                        int lastIndex = column.lastIndexOf(suffixIn);
                        column = column.substring(0, lastIndex)
                                + column.substring(lastIndex + suffixIn.length());
                        List<Object> list = (List<Object>) value;
                        stringBuilder.append("`").append(column).append("`");
                        stringBuilder.append(" in (");
                        if (!list.isEmpty()) {
                            list.forEach(str -> {
                                stringBuilder.append("'").append(str).append("',");
                            });
                        } else {
                            stringBuilder.append("'null',");
                        }
                        stringBuilder.deleteCharAt(stringBuilder.toString().length() - 1);
                        stringBuilder.append(")");
                    } else if (column.endsWith(suffixNotIn)) {
                        stringBuilder.append(" and ");
                        int lastIndex = column.lastIndexOf(suffixNotIn);
                        column = column.substring(0, lastIndex)
                                + column.substring(lastIndex + suffixNotIn.length());
                        List<Object> list = (List<Object>) value;
                        stringBuilder.append("`").append(column).append("`");
                        stringBuilder.append(" not in (");
                        if (!list.isEmpty()) {
                            list.forEach(str -> {
                                stringBuilder.append("'").append(str).append("',");
                            });
                        } else {
                            stringBuilder.append("'null',");
                        }
                        stringBuilder.deleteCharAt(stringBuilder.toString().length() - 1);
                        stringBuilder.append(")");
                    } else if (column.endsWith(suffixNull)) {
                        stringBuilder.append(" and ");
                        int lastIndex = column.lastIndexOf(suffixNull);
                        column = column.substring(0, lastIndex)
                                + column.substring(lastIndex + suffixNull.length());
                        stringBuilder.append("`").append(column).append("`").append(" is null");
                    } else if (column.endsWith(suffixNotNull)) {
                        stringBuilder.append(" and ");
                        int lastIndex = column.lastIndexOf(suffixNotNull);
                        column = column.substring(0, lastIndex)
                                + column.substring(lastIndex + suffixNotNull.length());
                        stringBuilder.append("`").append(column).append("`").append(" is not null");
                    } else if (column.equals(suffixApplySql)) {
                        stringBuilder.append(" and ");
                        stringBuilder.append("(").append(value).append(")");
                    } else if (column.startsWith("(") && column.endsWith(")")) {
                        stringBuilder.append(" and ");
                        column = key.substring(0, key.length() - 1);
                        stringBuilder.append("`").append(column).append("`").append("=").append("'").append(value).append("')");
                    } else {
                        stringBuilder.append(" and ");
                        stringBuilder.append("`").append(column).append("`").append("=");
                        if ("true".equals(value.toString()) || "false".equals(value.toString())) {
                            stringBuilder.append(value);
                        } else {
                            stringBuilder.append("'").append(value).append("'");
                        }
                    }
                });
        stringBuilder.append(orderLimitSql);
        return stringBuilder.toString();
    }

    private static String formatPageSqlCondition(Map<String, Object> map) {
        StringBuilder limitSql = new StringBuilder();
        StringBuilder orderBySql = new StringBuilder();
        StringBuilder groupBySql = new StringBuilder();
        if (map.containsKey("current") & map.containsKey("size")) {
            int current = (int) map.get("current");
            int size = (int) map.get("size");
            limitSql.append(" limit ").append((current - 1) * size).append(",").append(size);
        }
        if (map.containsKey("orderBy")) {
            String orderBy = map.get("orderBy").toString();
            String[] orderByArr = orderBy.split(",");
            orderBySql.append(" order by ");
            for (String name : orderByArr) {
                String[] nameArr = name.split("_");
                orderBySql.append("`").append(ResultSetUtil.humpToLine(nameArr[0])).append("` ").append(nameArr[1]).append(",");
            }
            orderBySql.deleteCharAt(orderBySql.toString().length() - 1);
        }
        if (map.containsKey("groupBy")) {
            String groupBy = map.get("groupBy").toString();
            String[] groupByArr = groupBy.split("-");
            groupBySql.append(" group by ");
            for (String name : groupByArr) {
                groupBySql.append("`").append(ResultSetUtil.humpToLine(name)).append("` ").append(",");
            }
            groupBySql.deleteCharAt(groupBySql.toString().length() - 1);
        }

        map.remove("current");
        map.remove("size");
        map.remove("orderBy");
        map.remove("groupBy");
        return orderBySql.toString() + groupBySql.toString() + limitSql.toString();
    }

    public static String formatSelectByIdSql(Object obj) throws Exception {
        String tableName = obj.getClass().getSimpleName();
        tableName = ResultSetUtil.humpToLine(tableName);

        Field[] declaredFields = obj.getClass().getDeclaredFields();
        Map<String, Object> map = new HashMap<>();
        for (Field field : declaredFields) {
            if (field.isAnnotationPresent(TableKey.class)) {
                field.setAccessible(true);
                map.put(field.getName(), field.get(obj));
                break;
            }
            if (field.isAnnotationPresent(TableId.class)) {
                field.setAccessible(true);
                if (StringUtil.isEmpty(field.getAnnotation(TableId.class).value())) {
                    map.put(field.getName(), field.get(obj));
                } else {
                    map.put(field.getAnnotation(TableId.class).value(), field.get(obj));
                }
                break;
            }
        }
        if (map.isEmpty()) {
            Field idField = obj.getClass().getDeclaredField("id");
            idField.setAccessible(true);
            map.put("id", idField.get(obj));
        }

        StringBuilder sql = new StringBuilder("select * from " + tableName + " where ");

        for (String key : map.keySet()) {
            sql.append(humpToLine(key)).append(" = '").append(map.get(key)).append("'");
        }

        return sql.toString();
    }

    /*
     * 此方法不设计到查某一个具体的主键有几条数据，
     * 因此不需要添加TableId的注解逻辑
     * */
    public static String formatSelectCountSql(Object obj) throws Exception {
        String tableName = obj.getClass().getSimpleName();
        tableName = ResultSetUtil.humpToLine(tableName);

        StringBuilder stringBuffer = new StringBuilder();
        stringBuffer.append(" where 1=1 ");
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            if (field.isAnnotationPresent(NotTableField.class)) {
                continue;
            }
            if (field.isAnnotationPresent(TableField.class)) {
                if (!field.getAnnotation(TableField.class).exist()) {
                    continue;
                }
            }
            field.setAccessible(true);
            if (StringUtil.isEmpty(field.get(obj))) {
                continue;
            }
            String column = humpToLine(field.getName());
            stringBuffer.append(" and `").append(column).append("`=");
            if (field.getType().getSimpleName().equals(Boolean.class.getSimpleName())) {
                stringBuffer.append(field.get(obj));
            } else {
                stringBuffer.append("'").append(field.get(obj)).append("'");
            }
        }

        return "select count(1) from " + tableName + stringBuffer.toString();
    }

    public static String formatSelectCountSql(Class clazz, Map<String, Object> map) throws Exception {
        String tableName = clazz.getSimpleName();
        tableName = ResultSetUtil.humpToLine(tableName);

        return "select count(1) from " + tableName + formatSqlCondition(map);
    }

    /*
     * 此方法不设计到getById，
     * 因此不需要添加TableId的注解逻辑
     * */
    public static String formatSelectSql(Object obj) throws Exception {
        String tableName = obj.getClass().getSimpleName();
        tableName = ResultSetUtil.humpToLine(tableName);

        StringBuilder stringBuffer = new StringBuilder();
        stringBuffer.append(" where 1=1 ");
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            if (field.isAnnotationPresent(NotTableField.class)) {
                continue;
            }
            if (field.isAnnotationPresent(TableField.class)) {
                if (!field.getAnnotation(TableField.class).exist()) {
                    continue;
                }
            }
            field.setAccessible(true);
            if (StringUtil.isEmpty(field.get(obj))) {
                continue;
            }
            String column = humpToLine(field.getName());
            stringBuffer.append(" and `").append(column).append("`=");
            if (field.getType().getSimpleName().equals(Boolean.class.getSimpleName())) {
                stringBuffer.append(field.get(obj));
            } else {
                stringBuffer.append("'").append(field.get(obj)).append("'");
            }
        }
        if (stringBuffer.toString().endsWith("1=1 ")) {
            throw new Exception("关键参数缺失");
        }
        return "select * from " + tableName + stringBuffer.toString() + " limit 1";
    }

    public static String formatSelectSql(Map<String, Object> map, Class clazz) throws Exception {
        String tableName = clazz.getSimpleName();
        tableName = ResultSetUtil.humpToLine(tableName);
        String condition = formatSqlCondition(map);
        if (condition.endsWith("1=1 ")) {
            throw new Exception("关键参数缺失");
        }
        return "select * from " + tableName + condition + " limit 1";
    }

    public static String formatSelectSql(Map<String, Object> map, String sql) throws Exception {
        String condition = formatSqlCondition(map);
        return sql + condition;
    }

    public static String formatInsertSql(Object obj) throws Exception {
        String tableName = obj.getClass().getSimpleName();
        tableName = ResultSetUtil.humpToLine(tableName);

        StringBuilder stringBuffer = new StringBuilder();
        stringBuffer.append("insert into ").append(tableName);
        StringBuilder stringBufferBe = new StringBuilder();
        StringBuilder stringBufferAf = new StringBuilder();

        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            if (field.isAnnotationPresent(NotTableField.class)) {
                continue;
            }
            if (field.isAnnotationPresent(TableField.class)) {
                if (!field.getAnnotation(TableField.class).exist()) {
                    continue;
                }
                //解决字段不是根据驼峰与下划线的转换规则的情况
                if (StringUtil.isNotEmpty(field.getAnnotation(TableField.class).value())
                        && StringUtil.isNotEmpty(StringUtil.isEmpty(field.get(obj)))) {
                    stringBufferBe.append("`").append(field.getAnnotation(TableField.class).value()).append("`").append(",");
                    if (field.getType().getSimpleName().equals(Boolean.class.getSimpleName())) {
                        stringBufferAf.append(field.get(obj));
                    } else {
                        String replaceStr = field.get(obj).toString();
                        stringBufferAf.append("'").append(replaceStr.replace("'", "^")).append("'");
                    }
                    stringBufferAf.append(",");
                    continue;
                }
            }
            if ("id".equals(field.getName())) {
                if (StringUtil.isEmpty(field.get(obj))) {
                    if (field.isAnnotationPresent(TableId.class) && IdType.AUTO.equals(field.getAnnotation(TableId.class).type())) {
                        continue;
                    }
                    field.set(obj, UUID.randomUUID().toString());
                }
            } else if ("createTime".equals(field.getName()) || "updateTime".equals(field.getName())) {
                if (StringUtil.isEmpty(field.get(obj))) {
                    if (field.getType().getSimpleName().equals(LocalDateTime.class.getSimpleName())) {
                        field.set(obj, LocalDateTime.now());
                    } else {
                        field.set(obj, LocalDateUtil.localDateTimeFormatyMdHms(LocalDateTime.now()));
                    }
                }
            }
            if (StringUtil.isEmpty(field.get(obj))) {
                continue;
            }
            if (containsSqlInjection(field.get(obj))) {
                throw new Exception("非法参数");
            }

            String column = humpToLine(field.getName());
            stringBufferBe.append("`").append(column).append("`").append(",");
            if (field.getType().getSimpleName().equals(Boolean.class.getSimpleName())) {
                stringBufferAf.append(field.get(obj));
            } else {
                String replaceStr = field.get(obj).toString();
                stringBufferAf.append("'").append(replaceStr.replace("'", "^")).append("'");
            }
            stringBufferAf.append(",");
        }

        stringBufferBe.deleteCharAt(stringBufferBe.toString().length() - 1);
        stringBufferAf.deleteCharAt(stringBufferAf.toString().length() - 1);
        stringBuffer.append("(").append(stringBufferBe).append(") values (").append(stringBufferAf).append(")");

        return stringBuffer.toString();
    }

    public static String formatUpdateByIdSql(Object obj) throws Exception {
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        Map<String, Object> map = new HashMap<>();
        for (Field field : declaredFields) {
            if (field.isAnnotationPresent(TableKey.class)) {
                field.setAccessible(true);
                map.put(field.getName(), field.get(obj));
                break;
            }
            if (field.isAnnotationPresent(TableId.class)) {
                field.setAccessible(true);
                if (StringUtil.isEmpty(field.getAnnotation(TableId.class).value())) {
                    map.put(field.getName(), field.get(obj));
                } else {
                    map.put(field.getAnnotation(TableId.class).value(), field.get(obj));
                }
                break;
            }
        }
        if (map.isEmpty()) {
            Field idField = obj.getClass().getDeclaredField("id");
            idField.setAccessible(true);
            map.put("id", idField.get(obj));
        }

        return formatUpdateSql(obj, map);
    }

    public static String formatUpdateSql(Object obj, Map<String, Object> whereMap) throws Exception {
        String tableName = obj.getClass().getSimpleName();
        tableName = ResultSetUtil.humpToLine(tableName);

        StringBuilder stringBuffer = new StringBuilder();
        stringBuffer.append("update ").append(tableName).append(" set ");
        Field[] superDeclaredFields = obj.getClass().getSuperclass().getDeclaredFields();
        for (Field field : superDeclaredFields) {
            field.setAccessible(true);
            if ("emptyField".equals(field.getName()) && StringUtil.isNotEmpty(field.get(obj))) {
                List<String> emptyFields = (List<String>) field.get(obj);
                if (null == emptyFields) {
                    continue;
                }
                for (String fieldName : emptyFields) {
                    stringBuffer.append("`").append(humpToLine(fieldName)).append("`").append("=null,");
                }
            }
        }

        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            if (field.isAnnotationPresent(NotTableField.class)) {
                continue;
            }
            if (field.isAnnotationPresent(TableField.class)) {
                if (!field.getAnnotation(TableField.class).exist()) {
                    continue;
                }
                //解决字段不是根据驼峰与下划线的转换规则的情况
                if (StringUtil.isNotEmpty(field.getAnnotation(TableField.class).value())
                        && StringUtil.isNotEmpty(StringUtil.isEmpty(field.get(obj)))) {
                    stringBuffer.append("`").append(field.getAnnotation(TableField.class).value()).append("`").append("=");
                    if (field.getType().getSimpleName().equals(Boolean.class.getSimpleName())) {
                        stringBuffer.append(field.get(obj));
                    } else {
                        String replaceStr = field.get(obj).toString();
                        stringBuffer.append("'").append(replaceStr.replace("'", "^")).append("'");
                    }
                    stringBuffer.append(",");
                    continue;
                }
            }
            if (field.isAnnotationPresent(TableKey.class) || field.isAnnotationPresent(TableId.class) || "id".equals(field.getName())) {
                continue;
            }

            if ("updateTime".equals(field.getName()) && field.get(obj) == null) {
                if (field.getType().getSimpleName().equals(LocalDateTime.class.getSimpleName())) {
                    field.set(obj, LocalDateTime.now());
                } else {
                    field.set(obj, LocalDateUtil.localDateTimeFormatyMdHms(LocalDateTime.now()));
                }
            }
            if (StringUtil.isEmpty(field.get(obj))) {
                continue;
            }
            if (containsSqlInjection(field.get(obj))) {
                throw new Exception("非法参数");
            }
            String column = humpToLine(field.getName());
            stringBuffer.append("`").append(column).append("`").append("=");
            if (field.getType().getSimpleName().equals(Boolean.class.getSimpleName())) {
                stringBuffer.append(field.get(obj));
            } else {
                stringBuffer.append("'").append(field.get(obj)).append("'");
            }
            stringBuffer.append(",");
        }

        if (whereMap.size() == 0) {
            throw new Exception("关键参数缺失");
        }

        stringBuffer.deleteCharAt(stringBuffer.toString().length() - 1);

        stringBuffer.append(formatSqlCondition(whereMap));
        if (stringBuffer.toString().endsWith("1=1 ")) {
            throw new Exception("关键参数缺失");
        }
        return stringBuffer.toString();
    }

    public static String formatRemoveByIdSql(Object obj) throws Exception {
        String tableName = obj.getClass().getSimpleName();
        tableName = ResultSetUtil.humpToLine(tableName);
        Map<String, Object> map = new HashMap<>();

        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            if (field.isAnnotationPresent(TableKey.class)) {
                field.setAccessible(true);
                map.put(field.getName(), field.get(obj));
                break;
            }
            if (field.isAnnotationPresent(TableId.class)) {
                field.setAccessible(true);
                if (StringUtil.isNotEmpty(field.getAnnotation(TableId.class).value())) {
                    map.put(field.getAnnotation(TableId.class).value(), field.get(obj));
                } else {
                    map.put(field.getName(), field.get(obj));
                }
                break;
            }
        }
        if (map.isEmpty()) {
            Field idField = obj.getClass().getDeclaredField("id");
            idField.setAccessible(true);
            map.put("id", idField.get(obj));
        }
        StringBuilder sql = new StringBuilder("delete from " + tableName + " where ");

        for (String key : map.keySet()) {
            sql.append(humpToLine(key)).append(" = '").append(map.get(key)).append("'");
        }

        return sql.toString();
    }

    public static String formatRemoveSql(Object obj) throws Exception {
        String tableName = obj.getClass().getSimpleName();
        tableName = ResultSetUtil.humpToLine(tableName);
        Map<String, Object> map = MapUtil.objectToMap(obj);

        String sql = "delete from " + tableName + formatSqlCondition(map);
        if (sql.endsWith("1=1 ")) {
            throw new Exception("关键参数缺失");
        }
        return sql;
    }

    public static AutoIncrementModel isExistAutoIncrement(Object obj) throws Exception {
        AutoIncrementModel incrementModel = new AutoIncrementModel();

        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            if (field.isAnnotationPresent(TableId.class)) {
                if (IdType.AUTO.equals(field.getAnnotation(TableId.class).type())) {
                    incrementModel.setIsAutoIncrement(true);
                    incrementModel.setFieldName(field.getName());
                    if (StringUtil.isNotEmpty(field.getAnnotation(TableId.class).value())) {
                        incrementModel.setColumnName(field.getAnnotation(TableId.class).value());
                    } else {
                        incrementModel.setColumnName(ResultSetUtil.humpToLine(field.getName()));
                    }
                    return incrementModel;
                }
            }
        }
        return incrementModel;
    }

    /**
     * 是否含有sql注入，返回true表示含有
     *
     * @param obj
     * @return
     */
    private static boolean containsSqlInjection(Object obj) {
        String objStr = obj.toString().toLowerCase();
        // 使用正则表达式匹配独立的SQL关键字，注意正则表达式需要根据实际需求调整
        String pattern = "\\b(and|exec|insert|select|drop|grant|alter|delete|update|count|chr|mid|master|truncate|char|declare|or|;)\\b";
        return objStr.matches(pattern);
    }
}
