真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

java中怎么利用正則表達(dá)式獲取sql中的表名

這篇文章給大家介紹java中怎么利用正則表達(dá)式獲取sql中的表名,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

創(chuàng)新互聯(lián)專注于永登網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供永登營銷型網(wǎng)站建設(shè),永登網(wǎng)站制作、永登網(wǎng)頁設(shè)計(jì)、永登網(wǎng)站官網(wǎng)定制、微信平臺小程序開發(fā)服務(wù),打造永登網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供永登網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。

 /**
     * 表名解析
     */
    private final static Pattern P = Pattern
            .compile("\\s+from\\s+(\\w\\.)?(\\w+)(\\s+|,)(\\w*)|\\s+join\\s+(\\w\\.)?(\\w+)\\s+(\\w\\s)*on", Pattern.CASE_INSENSITIVE);

/**
     * 預(yù)處理sql
     * @param sql sql
     * @return 處理后sql
     * @throws Exception 異常
     */
    private static String preHandleSql(String sql,boolean removeBrackets) throws Exception {
        // 1. 統(tǒng)一換行符
        if (sql.contains("\r\n")) {
            sql = sql.replaceAll("\r\n", "\n");
        } else {
            sql = sql.replaceAll("\r", "\n");
        }
        // 2. 去掉注釋
        String[] rows = sql.split("\n");
        StringBuilder sb = new StringBuilder(sql.length());
        for (String row : rows) {
            int indexOfComment = row.indexOf("--");
            if (indexOfComment == -1) {
                sb.append(row).append("\n");
            } else {
                sb.append(row, 0, indexOfComment).append("\n");
            }
        }
        if (removeBrackets) {
            sql = removeBrackets(sb);
        }
        // 4. 找到第一個select和from,其間的字段即是要查詢的字段列表
        return sql.toLowerCase();
    }


 /**
     * 括號消除:消除括號和括號中包含的內(nèi)容,非貪心模式
     * 例如:
     * 輸入select (ssss(sadf)sdfsdf(sdssf(sssdf)dsssf)dsslf) as a, (asdfsdf) as b, (asdfsdf) as c from dsfdf
     *            a組  b組  a組    c組    d組  b組   c組    d組      m組    m組      x組     x組
     *            A組                                     A組      B組    B組      C組     C組
     * 去掉select (去           掉           部           分) as a, (去掉部分) as b, (去掉部分) as c from dsfdf
     * 輸出select  as a,  as b,  as c from dsfdf
     *
     * @param str 消除前的字符串
     * @return 消除后的字符串
     * @throws Exception 括號不匹配
     */
    private static String removeBrackets(StringBuilder str) throws Exception {
        // 1. 收集括號組
        List bracketsContainer = new ArrayList<>();
        collectBrackets(str, 0, bracketsContainer);
        if (bracketsContainer.isEmpty()) {
            return str.toString();
        }
        // 2. 消除括號組
        StringBuilder newStr = new StringBuilder(str.length());
        int groupSize = bracketsContainer.size();
        for (int i = 0; i < groupSize; i++) {
            int[] currentBrackets = bracketsContainer.get(i);
            if (i == 0) {
                // 剛到第一組
                newStr.append(str.subSequence(0, currentBrackets[0]));
            }
            if (i + 1 == groupSize) {
                // 已到最后一組
                newStr.append(str.subSequence(currentBrackets[1] + 1, str.length()));
            } else {
                // 未到最后一組
                int[] nextBrackets = bracketsContainer.get(i + 1);
                newStr.append(str.subSequence(currentBrackets[1] + 1, nextBrackets[0]));
            }
        }
        return newStr.toString();
    }

    /**
     * 收集括號組
     *
     * @param str 消除前的字符串
     * @param fromIndex 從哪開始找括號
     * @param bracketsContainer 括號組容器
     * @throws Exception 括號不匹配、括號嵌套層級過多
     */
    private static void collectBrackets(StringBuilder str, int fromIndex, List bracketsContainer) throws Exception {
        int firstLeftBracket = str.indexOf("(", fromIndex + 1);
        int nextLeftBracket = firstLeftBracket;
        // SQL中不包含左括號時,直接返回
        if (firstLeftBracket == -1) {
            return;
        }
        // 括號層級(因?yàn)榍懊嬉呀?jīng)找到一個左括號,所以初始值為1)
        int level = 1;
        int nextRightBracket = str.indexOf(")", fromIndex + 1);
        if (nextRightBracket == -1) {
            throw new Exception("括號不匹配");
        }
        // 避免死循環(huán)
        int maxLevel = 1000;
        do {
            int tempLeftBracket = str.indexOf("(", nextLeftBracket + 1);
            if (tempLeftBracket == -1 || tempLeftBracket > nextRightBracket) {
                // 找不到下一個左括號或者下一個左括號已屬于下一個括號組
                break;
            } else {
                nextLeftBracket = tempLeftBracket;
            }
            nextRightBracket = str.indexOf(")", nextRightBracket + 1);
            if (nextRightBracket == -1) {
                throw new Exception("括號不匹配");
            }
            level++;
        } while (level <= maxLevel);
        if (level >= maxLevel) {
            throw new Exception("括號嵌套層級過多");
        }
        // 把收集到的括號組放入容器
        bracketsContainer.add(new int[] {firstLeftBracket, nextRightBracket});
        // 遞歸
        collectBrackets(str, nextRightBracket, bracketsContainer);
    }


/**
     * 解析sql中的表名
     * @param sql sql
     * @return 表名
     * @throws Exception 異常
     */
    public static List parseSqlRefTables(String sql) throws Exception {
        List tableNames = Lists.newArrayList();
        String newSql = StringUtils.replaceAll(preHandleSql(sql, false),"\n"," ");
        Matcher m = p.matcher(newSql);
        while (m.find()) {
            tableNames.add(m.group());
        }
        List result = Lists.newArrayList();
        for (String tableName : tableNames) {
            String trimTableName = StringUtils.split(tableName, " ")[1].trim();
            if (trimTableName.contains(",")) {
                result.addAll(Arrays.asList(StringUtils.split(trimTableName, ",")));
            } else {
                result.add(trimTableName);
            }
        }
        return result.parallelStream().distinct().collect(Collectors.toList());
    }

    public static void main(String[] args) throws Exception {
        String data1 = "SELECT dma_t.\"id\", dma_t.\"name\", dma_t.area_border, dma_t.lat_lng, dma_t.level, leak_t.lossf, leak_t.\"day\", leak_t.avgf, leak_t.background_loss, leak_t.nmf, leak_t.normal_use, leak_t.supply FROM la_leak_t leak_t, ( SELECT MAX (dma_id) AS dma_id, MAX (\"day\") AS \"day\" FROM la_leak_t WHERE org_id = ${orgId} GROUP BY dma_id ) recent_t, mdm_dmaarea_m_t dma_t WHERE leak_t.dma_id = recent_t.dma_id AND leak_t.\"day\" = recent_t.\"day\" AND leak_t.dma_id = dma_t.\"id\"";
        List tableNames = parseSqlRefTables(data1);
        tableNames.forEach(System.out::println);
    }

關(guān)于java中怎么利用正則表達(dá)式獲取sql中的表名就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。


網(wǎng)站名稱:java中怎么利用正則表達(dá)式獲取sql中的表名
網(wǎng)站網(wǎng)址:http://weahome.cn/article/gpdhci.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部