现在的位置: 首页 > 综合 > 正文

将多条sql根据表名合并成多值sql的正规表达式分组应用

2014年01月20日 ⁄ 综合 ⁄ 共 2181字 ⁄ 字号 评论关闭
package cn.zwork.crm.testdata;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 将多条sql根据表名合并成多值sql的正规表达式分组应用
 *
 */
public class Test {

    public static void main(String[] args) {
        //下面进行测试
        //下面的sql可以认为是通过程序生成的sql,如果sql条数很多(如几百万),需要很长时间才能执行完。
        List<String> sqlList = new ArrayList<String>();
        sqlList.add("INSERT INTO BUSSINESS_1(EMPLOYEE_ID, OCCUR_DATE, ACTION_TYPE, MODULE) VALUES(17, '2012-9-17', 'insert', 'CUSTOMER')");
        sqlList.add("INSERT INTO BUSSINESS_1(EMPLOYEE_ID, OCCUR_DATE, ACTION_TYPE, MODULE) VALUES(17, '2012-9-17', 'update', 'CUSTOMER')");
        sqlList.add("INSERT INTO BUSSINESS_2(EMPLOYEE_ID, OCCUR_DATE, ACTION_TYPE, MODULE) VALUES(17, '2012-9-17', 'insert', 'PERSON')");
        sqlList.add("INSERT INTO BUSSINESS_2(EMPLOYEE_ID, OCCUR_DATE, ACTION_TYPE, MODULE) VALUES(17, '2012-9-17', 'update', 'PERSON')");
        
        //通过合并sql,使sql的条数减少,本例中由四条减少到2条。在实际项目中,由100万减少到20几万。
        List<String> sql = mergeSql(sqlList);
        System.out.println(sql);
        /*
         * 结果为,用这个结果生成文本文件,再在数据库上执行
         * INSERT INTO BUSSINESS_2(EMPLOYEE_ID, OCCUR_DATE, ACTION_TYPE, MODULE)  VALUES (17, '2012-9-17', 'insert', 'PERSON'),(17, '2012-9-17', 'update', 'PERSON')
         * INSERT INTO BUSSINESS_1(EMPLOYEE_ID, OCCUR_DATE, ACTION_TYPE, MODULE)  VALUES (17, '2012-9-17', 'insert', 'CUSTOMER'),(17, '2012-9-17', 'update', 'CUSTOMER')
         * 
         * */
    }

    /**
     * 
     * 将多条sql根据表名合并成多值sql.
     * 应用场景:在做几百万测试数据时(通过程序生成单条sql),执行单条sql,效率很低,通过合并后大大提高了执行效率。
     * 
     * 
     * @param sqlList
     * @return
     */
    private static List<String> mergeSql(List<String> sqlList) {
        List<String> result;
        Map<String, String> sqlGroup = new HashMap<String, String>();
        Pattern p = Pattern.compile("(INSERT *INTO)(.*)( *\\(.*\\) *)VALUES(.*)");
        /*
         * 详细说明一下表达式:
         * 1 ()用来分组,本例中共分四组
         * 2 \\ 表示转义符,本例中(和)需要转义,即\\(和\\)
         * 3 . 表示任何字符,包括空格
         * 4 X* X被匹配零次或多次,本例中空格和.被匹配零次或多次
         * 5 第一组匹配:INSERT INTO,第二组匹配:表名,第三组匹配:列,第四组匹配:值
         * */

        for (String eachSql : sqlList) {
            Matcher m = p.matcher(eachSql);
            if (m.matches()) {
                String op = m.group(1);
                String tableName = m.group(2).trim();//表名
                String column = m.group(3);//列
                String value = m.group(4);//值

                if (sqlGroup.get(tableName) != null) {
                    String sql = sqlGroup.get(tableName);
                    sql += "," + value;
                    sqlGroup.put(tableName, sql);
                } else {
                    String sql = op + " " + tableName + column + " VALUES " + value;
                    sqlGroup.put(tableName, sql);
                }
            }
        }
        // 将map中的值,转成list返回
        result = new ArrayList(sqlGroup.values());

        return result;
    }
}

抱歉!评论已关闭.