src/main/java/com/aliyun/ha3engine/jdbc/Ha3PreparedStatement.java [487:619]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                this.ha3ResultSet = new Ha3ResultSet(result, this);
            } else {
                boolean canConvert = true;
                String originalSql = sql;

                // 正则表达式匹配 SELECT 关键字，忽略大小写
                Pattern selectPattern = Pattern.compile("\\bSELECT\\b", Pattern.CASE_INSENSITIVE);

                Matcher selectMatcher = selectPattern.matcher(sql);

                // 计算匹配到的 SELECT 关键字数量
                int selectCount = 0;
                while (selectMatcher.find()) {
                    selectCount++;
                }

                String beginSql = "";
                String endSql = "";
                int firstIndex = -1;
                int lastIndex = -1;
                if (selectCount > 1) {
                    firstIndex = sql.indexOf("(");
                    lastIndex = sql.lastIndexOf(")");
                    if (-1 != firstIndex && -1 != lastIndex) {
                        beginSql = sql.substring(0, firstIndex + 1);
                        endSql = sql.substring(lastIndex, sql.length());
                        sql = sql.substring(firstIndex + 1, lastIndex);
                    }
                }

                // 提取LIMIT子句中的常量值
                Pattern limitPattern = Pattern.compile("(?i)limit\\s+(\\d+)", Pattern.CASE_INSENSITIVE);
                Matcher limitMatcher = limitPattern.matcher(sql);
                int limitValue = -1;
                if (limitMatcher.find()) {
                    limitValue = Integer.parseInt(limitMatcher.group(1));
                    sql = sql.replaceFirst("(?i)limit\\s+\\d+", "");
                }

                // 提取OFFSET子句中的常量值
                Pattern offsetPattern = Pattern.compile("(?i)offset\\s+(\\d+)", Pattern.CASE_INSENSITIVE);
                Matcher offsetMatcher = offsetPattern.matcher(sql);
                int offsetValue = -1;
                if (offsetMatcher.find()) {
                    offsetValue = Integer.parseInt(offsetMatcher.group(1));
                    sql = sql.replaceFirst("(?i)offset\\s+\\d+", "");
                }

                // 创建不区分大小写的识别where的Pattern对象
                Pattern pattern = Pattern.compile(Pattern.quote("where"), Pattern.CASE_INSENSITIVE);
                Matcher matcher = pattern.matcher(sql);
                String firstPart = "";
                String secondPart = "";
                String thirdPart = "";
                if (matcher.find()) {
                    // 查询的第一部分
                    firstPart = sql.substring(0, matcher.start());
                    // 查询的第二部分
                    secondPart = sql.substring(matcher.start(), sql.length());
                    Pattern groupByPattern = Pattern.compile(Pattern.quote("group by"), Pattern.CASE_INSENSITIVE);
                    Matcher groupByMatcher = groupByPattern.matcher(secondPart);
                    if (groupByMatcher.find()) {
                        // 查询的第三部分
                        thirdPart = secondPart.substring(groupByMatcher.start(), secondPart.length());
                        // 查询的第二部分
                        secondPart = secondPart.substring(0, groupByMatcher.start());
                    }
                } else {
                    firstPart = sql;
                }

                // 创建不区分大小写的识别case when的Pattern对象
                Pattern caseWhenPattern = Pattern.compile(Pattern.quote("case when"), Pattern.CASE_INSENSITIVE);
                Matcher caseWhenMatcher = caseWhenPattern.matcher(secondPart);
                if (caseWhenMatcher.find()) {
                    canConvert = false;
                }

                // 创建不区分大小写的识别in的Pattern对象
                Pattern inPattern = Pattern.compile(Pattern.quote(" in"), Pattern.CASE_INSENSITIVE);
                Matcher inMatcher = inPattern.matcher(secondPart);
                if (inMatcher.find()) {
                    canConvert = false;
                }

                final DbType dbType = JdbcConstants.MYSQL;
                // 参数化SQL是输出的参数保存在这个List中
                List<Object> outParameters = new ArrayList<Object>();
                String psql = "";
                if (secondPart != null && StringUtils.isNotEmpty(secondPart)) {
                    secondPart = "select * from mock " + secondPart;
                    if (canConvert) {
                        try {
                            psql = ParameterizedOutputVisitorUtils.parameterize(secondPart, dbType, outParameters);
                        } catch (Exception e) {
                            logger.info("sql can not convert to dynamic params!");
                            canConvert = false;
                        }
                    } else {
                        logger.info("sql can not convert to dynamic params!");
                    }

                    psql = psql.replace("SELECT *\n"
                            + "FROM mock\n", "");
                }

                psql = firstPart + psql + " " + thirdPart;

                // 恢复LIMIT子句
                if (limitValue > 0) {
                    int limitIndex = psql.length();
                    psql = psql.substring(0, limitIndex) + " LIMIT " + limitValue;
                }

                // 恢复OFFSET子句
                if (offsetValue >= 0) {
                    int offsetIndex = psql.length();
                    psql = psql.substring(0, offsetIndex) + " OFFSET " + offsetValue;
                }

                if ((selectCount > 1) && (-1 != firstIndex && -1 != lastIndex)) {
                    psql = beginSql + psql + endSql;
                }

                if (canConvert) {
                    try {
                        PreparedStatement preparedStatement = this.ha3Connection.prepareStatement(psql);
                        for (int i = 0; i < outParameters.size(); i++) {
                            preparedStatement.setObject(i + 1, outParameters.get(i));
                        }
                        Ha3KvPairBuilder kvPairBuilder = new Ha3KvPairBuilder();
                        kvPairBuilder.enableCache();
                        kvPairBuilder.setPrepareLevel("jni.post.optimize");
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



src/main/java/com/aliyun/ha3engine/jdbc/Ha3Statement.java [221:353]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                this.ha3ResultSet = new Ha3ResultSet(result, this);
            } else {
                boolean canConvert = true;
                String originalSql = sql;

                // 正则表达式匹配 SELECT 关键字，忽略大小写
                Pattern selectPattern = Pattern.compile("\\bSELECT\\b", Pattern.CASE_INSENSITIVE);

                Matcher selectMatcher = selectPattern.matcher(sql);

                // 计算匹配到的 SELECT 关键字数量
                int selectCount = 0;
                while (selectMatcher.find()) {
                    selectCount++;
                }

                String beginSql = "";
                String endSql = "";
                int firstIndex = -1;
                int lastIndex = -1;
                if (selectCount > 1) {
                    firstIndex = sql.indexOf("(");
                    lastIndex = sql.lastIndexOf(")");
                    if (-1 != firstIndex && -1 != lastIndex) {
                        beginSql = sql.substring(0, firstIndex + 1);
                        endSql = sql.substring(lastIndex, sql.length());
                        sql = sql.substring(firstIndex + 1, lastIndex);
                    }
                }

                // 提取LIMIT子句中的常量值
                Pattern limitPattern = Pattern.compile("(?i)limit\\s+(\\d+)", Pattern.CASE_INSENSITIVE);
                Matcher limitMatcher = limitPattern.matcher(sql);
                int limitValue = -1;
                if (limitMatcher.find()) {
                    limitValue = Integer.parseInt(limitMatcher.group(1));
                    sql = sql.replaceFirst("(?i)limit\\s+\\d+", "");
                }

                // 提取OFFSET子句中的常量值
                Pattern offsetPattern = Pattern.compile("(?i)offset\\s+(\\d+)", Pattern.CASE_INSENSITIVE);
                Matcher offsetMatcher = offsetPattern.matcher(sql);
                int offsetValue = -1;
                if (offsetMatcher.find()) {
                    offsetValue = Integer.parseInt(offsetMatcher.group(1));
                    sql = sql.replaceFirst("(?i)offset\\s+\\d+", "");
                }

                // 创建不区分大小写的识别where的Pattern对象
                Pattern pattern = Pattern.compile(Pattern.quote("where"), Pattern.CASE_INSENSITIVE);
                Matcher matcher = pattern.matcher(sql);
                String firstPart = "";
                String secondPart = "";
                String thirdPart = "";
                if (matcher.find()) {
                    // 查询的第一部分
                    firstPart = sql.substring(0, matcher.start());
                    // 查询的第二部分
                    secondPart = sql.substring(matcher.start(), sql.length());
                    Pattern groupByPattern = Pattern.compile(Pattern.quote("group by"), Pattern.CASE_INSENSITIVE);
                    Matcher groupByMatcher = groupByPattern.matcher(secondPart);
                    if (groupByMatcher.find()) {
                        // 查询的第三部分
                        thirdPart = secondPart.substring(groupByMatcher.start(), secondPart.length());
                        // 查询的第二部分
                        secondPart = secondPart.substring(0, groupByMatcher.start());
                    }
                } else {
                    firstPart = sql;
                }

                // 创建不区分大小写的识别case when的Pattern对象
                Pattern caseWhenPattern = Pattern.compile(Pattern.quote("case when"), Pattern.CASE_INSENSITIVE);
                Matcher caseWhenMatcher = caseWhenPattern.matcher(secondPart);
                if (caseWhenMatcher.find()) {
                    canConvert = false;
                }

                // 创建不区分大小写的识别in的Pattern对象
                Pattern inPattern = Pattern.compile(Pattern.quote(" in"), Pattern.CASE_INSENSITIVE);
                Matcher inMatcher = inPattern.matcher(secondPart);
                if (inMatcher.find()) {
                    canConvert = false;
                }

                final DbType dbType = JdbcConstants.MYSQL;
                // 参数化SQL是输出的参数保存在这个List中
                List<Object> outParameters = new ArrayList<Object>();
                String psql = "";
                if (secondPart != null && StringUtils.isNotEmpty(secondPart)) {
                    secondPart = "select * from mock " + secondPart;
                    if (canConvert) {
                        try {
                            psql = ParameterizedOutputVisitorUtils.parameterize(secondPart, dbType, outParameters);
                        } catch (Exception e) {
                            logger.info("sql can not convert to dynamic params!");
                            canConvert = false;
                        }
                    } else {
                        logger.info("sql can not convert to dynamic params!");
                    }

                    psql = psql.replace("SELECT *\n"
                        + "FROM mock\n", "");
                }

                psql = firstPart + psql + " " + thirdPart;

                // 恢复LIMIT子句
                if (limitValue > 0) {
                    int limitIndex = psql.length();
                    psql = psql.substring(0, limitIndex) + " LIMIT " + limitValue;
                }

                // 恢复OFFSET子句
                if (offsetValue >= 0) {
                    int offsetIndex = psql.length();
                    psql = psql.substring(0, offsetIndex) + " OFFSET " + offsetValue;
                }

                if ((selectCount > 1) && (-1 != firstIndex && -1 != lastIndex)) {
                    psql = beginSql + psql + endSql;
                }

                if (canConvert) {
                    try {
                        PreparedStatement preparedStatement = this.ha3Connection.prepareStatement(psql);
                        for (int i = 0; i < outParameters.size(); i++) {
                            preparedStatement.setObject(i + 1, outParameters.get(i));
                        }
                        Ha3KvPairBuilder kvPairBuilder = new Ha3KvPairBuilder();
                        kvPairBuilder.enableCache();
                        kvPairBuilder.setPrepareLevel("jni.post.optimize");
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



